1 /*
2  * Copyright 2021 HIMSA II K/S - www.himsa.com.
3  * Represented by EHIMA - 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 <bluetooth/log.h>
19 #include <com_android_bluetooth_flags.h>
20 #include <flag_macros.h>
21 #include <gmock/gmock.h>
22 #include <gtest/gtest.h>
23 #include <log/log.h>
24 
25 #include <chrono>
26 
27 #include "bta/csis/csis_types.h"
28 #include "bta_gatt_api_mock.h"
29 #include "bta_gatt_queue_mock.h"
30 #include "bta_groups.h"
31 #include "bta_le_audio_api.h"
32 #include "bta_le_audio_broadcaster_api.h"
33 #include "btif/include/mock_core_callbacks.h"
34 #include "btif_storage_mock.h"
35 #include "btm_api_mock.h"
36 #include "btm_iso_api.h"
37 #include "common/message_loop_thread.h"
38 #include "fake_osi.h"
39 #include "gatt/database_builder.h"
40 #include "hardware/bt_gatt_types.h"
41 #include "hardware/bt_le_audio.h"
42 #include "hci/controller_interface_mock.h"
43 #include "internal_include/stack_config.h"
44 #include "le_audio/codec_manager.h"
45 #include "le_audio/mock_codec_interface.h"
46 #include "le_audio_health_status.h"
47 #include "le_audio_set_configuration_provider.h"
48 #include "le_audio_types.h"
49 #include "mock_codec_manager.h"
50 #include "mock_csis_client.h"
51 #include "mock_device_groups.h"
52 #include "mock_state_machine.h"
53 #include "stack/include/btm_status.h"
54 #include "test/common/mock_functions.h"
55 #include "test/mock/mock_main_shim_entry.h"
56 #include "test/mock/mock_stack_btm_iso.h"
57 
58 #define TEST_BT com::android::bluetooth::flags
59 
60 // TODO(b/369381361) Enfore -Wmissing-prototypes
61 #pragma GCC diagnostic ignored "-Wmissing-prototypes"
62 
63 using testing::_;
64 using testing::AnyNumber;
65 using testing::AtLeast;
66 using testing::AtMost;
67 using testing::DoAll;
68 using testing::Expectation;
69 using testing::InSequence;
70 using testing::Invoke;
71 using testing::Matcher;
72 using testing::Mock;
73 using testing::MockFunction;
74 using testing::NiceMock;
75 using testing::NotNull;
76 using testing::Return;
77 using testing::SaveArg;
78 using testing::SetArgPointee;
79 using testing::Test;
80 using testing::WithArg;
81 
82 using bluetooth::Uuid;
83 
84 using namespace bluetooth::le_audio;
85 
86 using bluetooth::le_audio::LeAudioCodecConfiguration;
87 using bluetooth::le_audio::LeAudioDeviceGroup;
88 using bluetooth::le_audio::LeAudioHealthStatus;
89 using bluetooth::le_audio::LeAudioSinkAudioHalClient;
90 using bluetooth::le_audio::LeAudioSourceAudioHalClient;
91 
92 using bluetooth::le_audio::DsaMode;
93 using bluetooth::le_audio::DsaModes;
94 using bluetooth::le_audio::types::AudioContexts;
95 using bluetooth::le_audio::types::BidirectionalPair;
96 using bluetooth::le_audio::types::LeAudioContextType;
97 
98 extern struct fake_osi_alarm_set_on_mloop fake_osi_alarm_set_on_mloop_;
99 
100 constexpr int max_num_of_ases = 5;
101 constexpr bluetooth::le_audio::types::LeAudioContextType kLeAudioDefaultConfigurationContext =
102         bluetooth::le_audio::types::LeAudioContextType::UNSPECIFIED;
103 
104 static constexpr char kNotifyUpperLayerAboutGroupBeingInIdleDuringCall[] =
105         "persist.bluetooth.leaudio.notify.idle.during.call";
106 
107 void osi_property_set_bool(const char* key, bool value);
108 
109 // Disables most likely false-positives from base::SplitString()
__asan_default_options()110 extern "C" const char* __asan_default_options() { return "detect_container_overflow=0"; }
111 
112 std::atomic<int> num_async_tasks;
113 static base::MessageLoop* message_loop_;
114 bluetooth::common::MessageLoopThread message_loop_thread("test message loop");
get_main_thread()115 bluetooth::common::MessageLoopThread* get_main_thread() { return &message_loop_thread; }
116 
do_in_main_thread(base::OnceClosure task)117 bt_status_t do_in_main_thread(base::OnceClosure task) {
118   if (!message_loop_) {
119     return BT_STATUS_FAIL;
120   }
121 
122   // Wrap the task with task counter so we could later know if there are
123   // any callbacks scheduled and we should wait before performing some actions
124   if (!message_loop_thread.DoInThread(
125               FROM_HERE, base::BindOnce(
126                                  [](base::OnceClosure task, std::atomic<int>& num_async_tasks) {
127                                    std::move(task).Run();
128                                    num_async_tasks--;
129                                  },
130                                  std::move(task), std::ref(num_async_tasks)))) {
131     bluetooth::log::error("failed to post task to task runner!");
132     return BT_STATUS_FAIL;
133   }
134   num_async_tasks++;
135   return BT_STATUS_SUCCESS;
136 }
137 
do_in_main_thread_delayed(base::OnceClosure task,std::chrono::microseconds)138 bt_status_t do_in_main_thread_delayed(base::OnceClosure task, std::chrono::microseconds /*delay*/) {
139   /* For testing purpose it is ok to just skip delay */
140   return do_in_main_thread(std::move(task));
141 }
142 
get_main_message_loop()143 base::MessageLoop* get_main_message_loop() { return message_loop_; }
144 
init_message_loop_thread()145 static void init_message_loop_thread() {
146   num_async_tasks = 0;
147   message_loop_thread.StartUp();
148   if (!message_loop_thread.IsRunning()) {
149     FAIL() << "unable to create message loop thread.";
150   }
151 
152   if (!message_loop_thread.EnableRealTimeScheduling()) {
153     bluetooth::log::error("Unable to set real time scheduling");
154   }
155 
156   message_loop_ = message_loop_thread.message_loop();
157   if (message_loop_ == nullptr) {
158     FAIL() << "unable to get message loop.";
159   }
160 }
161 
cleanup_message_loop_thread()162 static void cleanup_message_loop_thread() {
163   message_loop_ = nullptr;
164   message_loop_thread.ShutDown();
165 }
166 
invoke_switch_codec_cb(bool)167 void invoke_switch_codec_cb(bool /*is_low_latency_buffer_size*/) {}
invoke_switch_buffer_size_cb(bool)168 void invoke_switch_buffer_size_cb(bool /*is_low_latency_buffer_size*/) {}
169 
170 const std::string kSmpOptions("mock smp options");
get_pts_avrcp_test(void)171 bool get_pts_avrcp_test(void) { return false; }
get_pts_secure_only_mode(void)172 bool get_pts_secure_only_mode(void) { return false; }
get_pts_conn_updates_disabled(void)173 bool get_pts_conn_updates_disabled(void) { return false; }
get_pts_crosskey_sdp_disable(void)174 bool get_pts_crosskey_sdp_disable(void) { return false; }
get_pts_smp_options(void)175 const std::string* get_pts_smp_options(void) { return &kSmpOptions; }
get_pts_smp_failure_case(void)176 int get_pts_smp_failure_case(void) { return 123; }
get_pts_force_eatt_for_notifications(void)177 bool get_pts_force_eatt_for_notifications(void) { return false; }
get_pts_connect_eatt_unconditionally(void)178 bool get_pts_connect_eatt_unconditionally(void) { return false; }
get_pts_connect_eatt_before_encryption(void)179 bool get_pts_connect_eatt_before_encryption(void) { return false; }
get_pts_unencrypt_broadcast(void)180 bool get_pts_unencrypt_broadcast(void) { return false; }
get_pts_eatt_peripheral_collision_support(void)181 bool get_pts_eatt_peripheral_collision_support(void) { return false; }
get_pts_force_le_audio_multiple_contexts_metadata(void)182 bool get_pts_force_le_audio_multiple_contexts_metadata(void) { return false; }
get_pts_le_audio_disable_ases_before_stopping(void)183 bool get_pts_le_audio_disable_ases_before_stopping(void) { return false; }
get_all(void)184 config_t* get_all(void) { return nullptr; }
185 
186 stack_config_t mock_stack_config{
187         .get_pts_avrcp_test = get_pts_avrcp_test,
188         .get_pts_secure_only_mode = get_pts_secure_only_mode,
189         .get_pts_conn_updates_disabled = get_pts_conn_updates_disabled,
190         .get_pts_crosskey_sdp_disable = get_pts_crosskey_sdp_disable,
191         .get_pts_smp_options = get_pts_smp_options,
192         .get_pts_smp_failure_case = get_pts_smp_failure_case,
193         .get_pts_force_eatt_for_notifications = get_pts_force_eatt_for_notifications,
194         .get_pts_connect_eatt_unconditionally = get_pts_connect_eatt_unconditionally,
195         .get_pts_connect_eatt_before_encryption = get_pts_connect_eatt_before_encryption,
196         .get_pts_unencrypt_broadcast = get_pts_unencrypt_broadcast,
197         .get_pts_eatt_peripheral_collision_support = get_pts_eatt_peripheral_collision_support,
198         .get_pts_force_le_audio_multiple_contexts_metadata =
199                 get_pts_force_le_audio_multiple_contexts_metadata,
200         .get_pts_le_audio_disable_ases_before_stopping =
201                 get_pts_le_audio_disable_ases_before_stopping,
202         .get_all = get_all,
203 };
stack_config_get_interface(void)204 const stack_config_t* stack_config_get_interface(void) { return &mock_stack_config; }
205 
IsLeAudioBroadcasterRunning()206 bool LeAudioBroadcaster::IsLeAudioBroadcasterRunning() { return false; }
207 
208 namespace bluetooth::le_audio {
209 class MockLeAudioSourceHalClient;
210 MockLeAudioSourceHalClient* mock_le_audio_source_hal_client_;
211 std::unique_ptr<LeAudioSourceAudioHalClient> owned_mock_le_audio_source_hal_client_;
212 bool is_audio_unicast_source_acquired;
213 
AcquireUnicast()214 std::unique_ptr<LeAudioSourceAudioHalClient> LeAudioSourceAudioHalClient::AcquireUnicast() {
215   if (is_audio_unicast_source_acquired) {
216     return nullptr;
217   }
218   is_audio_unicast_source_acquired = true;
219   return std::move(owned_mock_le_audio_source_hal_client_);
220 }
221 
DebugDump(int)222 void LeAudioSourceAudioHalClient::DebugDump(int /*fd*/) {}
223 
224 class MockLeAudioSinkHalClient;
225 MockLeAudioSinkHalClient* mock_le_audio_sink_hal_client_;
226 std::unique_ptr<LeAudioSinkAudioHalClient> owned_mock_le_audio_sink_hal_client_;
227 bool is_audio_unicast_sink_acquired;
228 
AcquireUnicast()229 std::unique_ptr<LeAudioSinkAudioHalClient> LeAudioSinkAudioHalClient::AcquireUnicast() {
230   if (is_audio_unicast_sink_acquired) {
231     return nullptr;
232   }
233   is_audio_unicast_sink_acquired = true;
234   return std::move(owned_mock_le_audio_sink_hal_client_);
235 }
236 
DebugDump(int)237 void LeAudioSinkAudioHalClient::DebugDump(int /*fd*/) {}
238 
GetTestAddress(uint8_t index)239 RawAddress GetTestAddress(uint8_t index) {
240   EXPECT_LT(index, UINT8_MAX);
241   RawAddress result = {{0xC0, 0xDE, 0xC0, 0xDE, 0x00, index}};
242   return result;
243 }
244 
245 class MockAudioHalClientCallbacks : public bluetooth::le_audio::LeAudioClientCallbacks {
246 public:
247   MOCK_METHOD((void), OnInitialized, (), (override));
248   MOCK_METHOD((void), OnConnectionState, (ConnectionState state, const RawAddress& address),
249               (override));
250   MOCK_METHOD((void), OnGroupStatus, (int group_id, GroupStatus group_status), (override));
251   MOCK_METHOD((void), OnGroupStreamStatus, (int group_id, GroupStreamStatus group_stream_status),
252               (override));
253   MOCK_METHOD((void), OnGroupNodeStatus,
254               (const RawAddress& bd_addr, int group_id, GroupNodeStatus node_status), (override));
255   MOCK_METHOD((void), OnAudioConf,
256               (uint8_t direction, int group_id, uint32_t snk_audio_location,
257                uint32_t src_audio_location, uint16_t avail_cont),
258               (override));
259   MOCK_METHOD((void), OnSinkAudioLocationAvailable,
260               (const RawAddress& bd_addr, uint32_t snk_audio_location), (override));
261   MOCK_METHOD((void), OnAudioLocalCodecCapabilities,
262               (std::vector<btle_audio_codec_config_t> local_input_capa_codec_conf,
263                std::vector<btle_audio_codec_config_t> local_output_capa_codec_conf),
264               (override));
265   MOCK_METHOD((void), OnAudioGroupCurrentCodecConf,
266               (int group_id, btle_audio_codec_config_t input_codec_conf,
267                btle_audio_codec_config_t output_codec_conf),
268               (override));
269   MOCK_METHOD((void), OnAudioGroupSelectableCodecConf,
270               (int group_id, std::vector<btle_audio_codec_config_t> input_selectable_codec_conf,
271                std::vector<btle_audio_codec_config_t> output_selectable_codec_conf),
272               (override));
273   MOCK_METHOD((void), OnHealthBasedRecommendationAction,
274               (const RawAddress& address, LeAudioHealthBasedAction action), (override));
275   MOCK_METHOD((void), OnHealthBasedGroupRecommendationAction,
276               (int group_id, LeAudioHealthBasedAction action), (override));
277   MOCK_METHOD((void), OnUnicastMonitorModeStatus,
278               (uint8_t direction, UnicastMonitorModeStatus status));
279 };
280 
281 class MockLeAudioSinkHalClient : public LeAudioSinkAudioHalClient {
282 public:
283   MockLeAudioSinkHalClient() = default;
284   MOCK_METHOD((bool), Start,
285               (const LeAudioCodecConfiguration& codecConfiguration,
286                LeAudioSinkAudioHalClient::Callbacks* audioReceiver, DsaModes dsa_modes),
287               (override));
288   MOCK_METHOD((void), Stop, (), (override));
289   MOCK_METHOD((size_t), SendData, (uint8_t* data, uint16_t size), (override));
290   MOCK_METHOD((void), ConfirmStreamingRequest, (), (override));
291   MOCK_METHOD((void), CancelStreamingRequest, (), (override));
292   MOCK_METHOD((void), UpdateRemoteDelay, (uint16_t delay), (override));
293   MOCK_METHOD((void), UpdateAudioConfigToHal, (const ::bluetooth::le_audio::offload_config&),
294               (override));
295   MOCK_METHOD((void), SuspendedForReconfiguration, (), (override));
296   MOCK_METHOD((void), ReconfigurationComplete, (), (override));
297 
298   MOCK_METHOD((void), OnDestroyed, ());
~MockLeAudioSinkHalClient()299   virtual ~MockLeAudioSinkHalClient() override { OnDestroyed(); }
300 };
301 
302 class MockLeAudioSourceHalClient : public LeAudioSourceAudioHalClient {
303 public:
304   MockLeAudioSourceHalClient() = default;
305   MOCK_METHOD((bool), Start,
306               (const LeAudioCodecConfiguration& codecConfiguration,
307                LeAudioSourceAudioHalClient::Callbacks* audioReceiver, DsaModes dsa_modes),
308               (override));
309   MOCK_METHOD((void), Stop, (), (override));
310   MOCK_METHOD((void), ConfirmStreamingRequest, (), (override));
311   MOCK_METHOD((void), CancelStreamingRequest, (), (override));
312   MOCK_METHOD((void), UpdateRemoteDelay, (uint16_t delay), (override));
313   MOCK_METHOD((void), UpdateAudioConfigToHal, (const ::bluetooth::le_audio::offload_config&),
314               (override));
315   MOCK_METHOD((std::optional<broadcaster::BroadcastConfiguration>), GetBroadcastConfig,
316               ((const std::vector<std::pair<types::LeAudioContextType, uint8_t>>&),
317                (const std::optional<std::vector<::bluetooth::le_audio::types::acs_ac_record>>&)),
318               (const override));
319   MOCK_METHOD((std::optional<::bluetooth::le_audio::set_configurations::AudioSetConfiguration>),
320               GetUnicastConfig, (const CodecManager::UnicastConfigurationRequirements&),
321               (const override));
322   MOCK_METHOD((void), UpdateBroadcastAudioConfigToHal,
323               (const ::bluetooth::le_audio::broadcast_offload_config&), (override));
324   MOCK_METHOD((void), SuspendedForReconfiguration, (), (override));
325   MOCK_METHOD((void), ReconfigurationComplete, (), (override));
326 
327   MOCK_METHOD((void), OnDestroyed, ());
~MockLeAudioSourceHalClient()328   virtual ~MockLeAudioSourceHalClient() override { OnDestroyed(); }
329 };
330 
331 class UnicastTestNoInit : public Test {
332 public:
333   bool use_handover_mode = false;
334 
335 protected:
RegisterSourceHalClientMock()336   void RegisterSourceHalClientMock() {
337     owned_mock_le_audio_source_hal_client_.reset(new NiceMock<MockLeAudioSourceHalClient>());
338     mock_le_audio_source_hal_client_ =
339             (MockLeAudioSourceHalClient*)owned_mock_le_audio_source_hal_client_.get();
340 
341     is_audio_unicast_source_acquired = false;
342     ON_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _))
343             .WillByDefault([this](const LeAudioCodecConfiguration& /*codec_configuration*/,
344                                   LeAudioSourceAudioHalClient::Callbacks* audioReceiver,
345                                   DsaModes /*dsa_modes*/) {
346               unicast_source_hal_cb_ = audioReceiver;
347               return true;
348             });
349     ON_CALL(*mock_le_audio_source_hal_client_, OnDestroyed).WillByDefault([]() {
350       mock_le_audio_source_hal_client_ = nullptr;
351       is_audio_unicast_source_acquired = false;
352     });
353   }
354 
RegisterSinkHalClientMock()355   void RegisterSinkHalClientMock() {
356     owned_mock_le_audio_sink_hal_client_.reset(new NiceMock<MockLeAudioSinkHalClient>());
357     mock_le_audio_sink_hal_client_ =
358             (MockLeAudioSinkHalClient*)owned_mock_le_audio_sink_hal_client_.get();
359 
360     is_audio_unicast_sink_acquired = false;
361     ON_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _))
362             .WillByDefault([this](const LeAudioCodecConfiguration& /*codec_configuration*/,
363                                   LeAudioSinkAudioHalClient::Callbacks* audioReceiver,
364                                   DsaModes /*dsa_modes*/) {
365               unicast_sink_hal_cb_ = audioReceiver;
366               return true;
367             });
368     ON_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed).WillByDefault([]() {
369       mock_le_audio_sink_hal_client_ = nullptr;
370       is_audio_unicast_sink_acquired = false;
371     });
372   }
373 
SetUpMockAudioHal()374   void SetUpMockAudioHal() {
375     /* Since these are returned by the Acquire() methods as unique_ptrs, we
376      * will not free them manually.
377      */
378     RegisterSourceHalClientMock();
379 
380     owned_mock_le_audio_sink_hal_client_.reset(new NiceMock<MockLeAudioSinkHalClient>());
381     mock_le_audio_sink_hal_client_ =
382             (MockLeAudioSinkHalClient*)owned_mock_le_audio_sink_hal_client_.get();
383 
384     owned_mock_le_audio_source_hal_client_.reset(new NiceMock<MockLeAudioSourceHalClient>());
385     mock_le_audio_source_hal_client_ =
386             (MockLeAudioSourceHalClient*)owned_mock_le_audio_source_hal_client_.get();
387 
388     is_audio_unicast_source_acquired = false;
389     ON_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _))
390             .WillByDefault([this](const LeAudioCodecConfiguration& /*codec_configuration*/,
391                                   LeAudioSourceAudioHalClient::Callbacks* audioReceiver,
392                                   DsaModes /*dsa_modes*/) {
393               unicast_source_hal_cb_ = audioReceiver;
394               return true;
395             });
396     ON_CALL(*mock_le_audio_source_hal_client_, OnDestroyed).WillByDefault([]() {
397       mock_le_audio_source_hal_client_ = nullptr;
398       is_audio_unicast_source_acquired = false;
399     });
400 
401     is_audio_unicast_sink_acquired = false;
402     ON_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _))
403             .WillByDefault([this](const LeAudioCodecConfiguration& /*codec_configuration*/,
404                                   LeAudioSinkAudioHalClient::Callbacks* audioReceiver,
405                                   DsaModes /*dsa_modes*/) {
406               unicast_sink_hal_cb_ = audioReceiver;
407               return true;
408             });
409     ON_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed).WillByDefault([]() {
410       mock_le_audio_sink_hal_client_ = nullptr;
411       is_audio_unicast_sink_acquired = false;
412     });
413 
414     ON_CALL(*mock_le_audio_sink_hal_client_, SendData)
415             .WillByDefault([](uint8_t* /*data*/, uint16_t size) { return size; });
416 
417     // HAL
418     ON_CALL(mock_hal_2_1_verifier, Call()).WillByDefault([]() -> bool { return true; });
419   }
420 
InjectGroupDeviceRemoved(const RawAddress & address,int group_id)421   void InjectGroupDeviceRemoved(const RawAddress& address, int group_id) {
422     group_callbacks_->OnGroupMemberRemoved(address, group_id);
423   }
424 
InjectGroupDeviceAdded(const RawAddress & address,int group_id)425   void InjectGroupDeviceAdded(const RawAddress& address, int group_id) {
426     bluetooth::Uuid uuid = bluetooth::le_audio::uuid::kCapServiceUuid;
427 
428     int group_members_num = 0;
429     for (const auto& [addr, id] : groups) {
430       if (id == group_id) {
431         group_members_num++;
432       }
433     }
434 
435     bool first_device = (group_members_num == 1);
436     do_in_main_thread(base::BindOnce(
437             [](const RawAddress& addr, int group_id, bluetooth::Uuid uuid,
438                bluetooth::groups::DeviceGroupsCallbacks* group_callbacks, bool first_device) {
439               if (first_device) {
440                 group_callbacks->OnGroupAdded(addr, uuid, group_id);
441               } else {
442                 group_callbacks->OnGroupMemberAdded(addr, group_id);
443               }
444             },
445             address, group_id, uuid, base::Unretained(this->group_callbacks_), first_device));
446   }
447 
InjectServiceChangedEvent(const RawAddress & address,uint16_t conn_id)448   void InjectServiceChangedEvent(const RawAddress& address, uint16_t conn_id) {
449     tBTA_GATTC_SERVICE_CHANGED event_data = {.remote_bda = address, .conn_id = conn_id};
450 
451     do_in_main_thread(base::BindOnce(
452             [](tBTA_GATTC_CBACK* gatt_callback, tBTA_GATTC_SERVICE_CHANGED event_data) {
453               gatt_callback(BTA_GATTC_SRVC_CHG_EVT, (tBTA_GATTC*)&event_data);
454             },
455             base::Unretained(this->gatt_callback), event_data));
456   }
457 
InjectConnectedEvent(const RawAddress & address,uint16_t conn_id,tGATT_STATUS status=GATT_SUCCESS)458   void InjectConnectedEvent(const RawAddress& address, uint16_t conn_id,
459                             tGATT_STATUS status = GATT_SUCCESS) {
460     ASSERT_NE(conn_id, GATT_INVALID_CONN_ID);
461     tBTA_GATTC_OPEN event_data = {
462             .status = status,
463             .conn_id = conn_id,
464             .client_if = gatt_if,
465             .remote_bda = address,
466             .transport = BT_TRANSPORT_LE,
467             .mtu = 240,
468     };
469 
470     if (status == GATT_SUCCESS) {
471       ASSERT_NE(peer_devices.count(conn_id), 0u);
472       peer_devices.at(conn_id)->connected = true;
473     }
474 
475     do_in_main_thread(base::BindOnce(
476             [](tBTA_GATTC_CBACK* gatt_callback, tBTA_GATTC_OPEN event_data) {
477               gatt_callback(BTA_GATTC_OPEN_EVT, (tBTA_GATTC*)&event_data);
478             },
479             base::Unretained(this->gatt_callback), event_data));
480   }
481 
InjectEncryptionChangedEvent(const RawAddress & address)482   void InjectEncryptionChangedEvent(const RawAddress& address) {
483     tBTA_GATTC_ENC_CMPL_CB event_data = {
484             .client_if = gatt_if,
485             .remote_bda = address,
486     };
487 
488     do_in_main_thread(base::BindOnce(
489             [](tBTA_GATTC_CBACK* gatt_callback, tBTA_GATTC_ENC_CMPL_CB event_data) {
490               gatt_callback(BTA_GATTC_ENC_CMPL_CB_EVT, (tBTA_GATTC*)&event_data);
491             },
492             base::Unretained(this->gatt_callback), event_data));
493   }
494 
TriggerDisconnectionFromApp(const RawAddress & address)495   void TriggerDisconnectionFromApp(const RawAddress& address) {
496     do_in_main_thread(base::BindOnce(
497             [](LeAudioClient* client, const RawAddress& address) { client->Disconnect(address); },
498             LeAudioClient::Get(), address));
499   }
500 
InjectDisconnectedEvent(uint16_t conn_id,tGATT_DISCONN_REASON reason=GATT_CONN_TERMINATE_LOCAL_HOST)501   void InjectDisconnectedEvent(uint16_t conn_id,
502                                tGATT_DISCONN_REASON reason = GATT_CONN_TERMINATE_LOCAL_HOST) {
503     ASSERT_NE(conn_id, GATT_INVALID_CONN_ID);
504     ASSERT_NE(peer_devices.count(conn_id), 0u);
505 
506     tBTA_GATTC_CLOSE event_data = {
507             .conn_id = conn_id,
508             .status = GATT_SUCCESS,
509             .client_if = gatt_if,
510             .remote_bda = peer_devices.at(conn_id)->addr,
511             .reason = reason,
512     };
513 
514     peer_devices.at(conn_id)->connected = false;
515     do_in_main_thread(base::BindOnce(
516             [](tBTA_GATTC_CBACK* gatt_callback, tBTA_GATTC_CLOSE event_data) {
517               gatt_callback(BTA_GATTC_CLOSE_EVT, (tBTA_GATTC*)&event_data);
518             },
519             base::Unretained(this->gatt_callback), event_data));
520   }
521 
InjectPhyChangedEvent(uint16_t conn_id,uint8_t tx_phy,uint8_t rx_phy,tGATT_STATUS status)522   void InjectPhyChangedEvent(uint16_t conn_id, uint8_t tx_phy, uint8_t rx_phy,
523                              tGATT_STATUS status) {
524     ASSERT_NE(conn_id, GATT_INVALID_CONN_ID);
525     tBTA_GATTC_PHY_UPDATE event_data = {
526             .conn_id = conn_id,
527             .tx_phy = tx_phy,
528             .rx_phy = rx_phy,
529             .status = status,
530     };
531 
532     do_in_main_thread(base::BindOnce(
533             [](tBTA_GATTC_CBACK* gatt_callback, tBTA_GATTC_PHY_UPDATE event_data) {
534               gatt_callback(BTA_GATTC_PHY_UPDATE_EVT, (tBTA_GATTC*)&event_data);
535             },
536             base::Unretained(this->gatt_callback), event_data));
537   }
538 
InjectSearchCompleteEvent(uint16_t conn_id)539   void InjectSearchCompleteEvent(uint16_t conn_id) {
540     ASSERT_NE(conn_id, GATT_INVALID_CONN_ID);
541     tBTA_GATTC_SEARCH_CMPL event_data = {
542             .conn_id = conn_id,
543             .status = GATT_SUCCESS,
544     };
545 
546     do_in_main_thread(base::BindOnce(
547             [](tBTA_GATTC_CBACK* gatt_callback, tBTA_GATTC_SEARCH_CMPL event_data) {
548               gatt_callback(BTA_GATTC_SEARCH_CMPL_EVT, (tBTA_GATTC*)&event_data);
549             },
550             base::Unretained(this->gatt_callback), event_data));
551   }
552 
InjectNotificationEvent(const RawAddress & test_address,uint16_t conn_id,uint16_t handle,std::vector<uint8_t> value)553   void InjectNotificationEvent(const RawAddress& test_address, uint16_t conn_id, uint16_t handle,
554                                std::vector<uint8_t> value) {
555     ASSERT_NE(conn_id, GATT_INVALID_CONN_ID);
556     tBTA_GATTC_NOTIFY event_data = {
557             .conn_id = conn_id,
558             .bda = test_address,
559             .handle = handle,
560             .len = (uint8_t)value.size(),
561             .is_notify = true,
562     };
563 
564     std::copy(value.begin(), value.end(), event_data.value);
565     do_in_main_thread(base::BindOnce(
566             [](tBTA_GATTC_CBACK* gatt_callback, tBTA_GATTC_NOTIFY event_data) {
567               gatt_callback(BTA_GATTC_NOTIF_EVT, (tBTA_GATTC*)&event_data);
568             },
569             base::Unretained(this->gatt_callback), event_data));
570   }
571 
InjectContextTypes(const RawAddress & test_address,uint16_t conn_id,uint16_t handle,AudioContexts sink_ctxs,AudioContexts source_ctxs)572   void InjectContextTypes(const RawAddress& test_address, uint16_t conn_id, uint16_t handle,
573                           AudioContexts sink_ctxs, AudioContexts source_ctxs) {
574     std::vector<uint8_t> contexts = {
575             (uint8_t)(sink_ctxs.value()), (uint8_t)(sink_ctxs.value() >> 8),
576             (uint8_t)(source_ctxs.value()), (uint8_t)(source_ctxs.value() >> 8)};
577 
578     InjectNotificationEvent(test_address, conn_id, handle, contexts);
579   }
580 
InjectSupportedContextTypes(const RawAddress & test_address,uint16_t conn_id,AudioContexts sink_ctxs,AudioContexts source_ctxs)581   void InjectSupportedContextTypes(const RawAddress& test_address, uint16_t conn_id,
582                                    AudioContexts sink_ctxs, AudioContexts source_ctxs) {
583     /* 0x0077 pacs->supp_contexts_char + 1 */
584     InjectContextTypes(test_address, conn_id, 0x0077, sink_ctxs, source_ctxs);
585     SyncOnMainLoop();
586   }
587 
InjectAvailableContextTypes(const RawAddress & test_address,uint16_t conn_id,AudioContexts sink_ctxs,AudioContexts source_ctxs,bool sync_on_mainloop=true)588   void InjectAvailableContextTypes(const RawAddress& test_address, uint16_t conn_id,
589                                    AudioContexts sink_ctxs, AudioContexts source_ctxs,
590                                    bool sync_on_mainloop = true) {
591     /* 0x0074 is pacs->avail_contexts_char + 1 */
592     InjectContextTypes(test_address, conn_id, 0x0074, sink_ctxs, source_ctxs);
593     if (sync_on_mainloop) {
594       SyncOnMainLoop();
595     }
596   }
597 
SetUpMockGatt()598   void SetUpMockGatt() {
599     // default action for GetCharacteristic function call
600     ON_CALL(mock_gatt_interface_, GetCharacteristic(_, _))
601             .WillByDefault(
602                     Invoke([&](uint16_t conn_id, uint16_t handle) -> const gatt::Characteristic* {
603                       std::list<gatt::Service>& services = peer_devices.at(conn_id)->services;
604                       for (auto const& service : services) {
605                         for (auto const& characteristic : service.characteristics) {
606                           if (characteristic.value_handle == handle) {
607                             return &characteristic;
608                           }
609                         }
610                       }
611 
612                       return nullptr;
613                     }));
614 
615     // default action for GetOwningService function call
616     ON_CALL(mock_gatt_interface_, GetOwningService(_, _))
617             .WillByDefault(Invoke([&](uint16_t conn_id, uint16_t handle) -> const gatt::Service* {
618               std::list<gatt::Service>& services = peer_devices.at(conn_id)->services;
619               for (auto const& service : services) {
620                 if (service.handle <= handle && service.end_handle >= handle) {
621                   return &service;
622                 }
623               }
624 
625               return nullptr;
626             }));
627 
628     // default action for ServiceSearchRequest function call
629     ON_CALL(mock_gatt_interface_, ServiceSearchRequest(_, _))
630             .WillByDefault(WithArg<0>(
631                     Invoke([&](uint16_t conn_id) { InjectSearchCompleteEvent(conn_id); })));
632 
633     // default action for GetServices function call
634     ON_CALL(mock_gatt_interface_, GetServices(_))
635             .WillByDefault(WithArg<0>(Invoke([&](uint16_t conn_id) -> std::list<gatt::Service>* {
636               return &peer_devices.at(conn_id)->services;
637             })));
638 
639     // default action for RegisterForNotifications function call
640     ON_CALL(mock_gatt_interface_, RegisterForNotifications(gatt_if, _, _))
641             .WillByDefault(Return(GATT_SUCCESS));
642 
643     // default action for DeregisterForNotifications function call
644     ON_CALL(mock_gatt_interface_, DeregisterForNotifications(gatt_if, _, _))
645             .WillByDefault(Return(GATT_SUCCESS));
646 
647     // default action for WriteDescriptor function call
648     ON_CALL(mock_gatt_queue_, WriteDescriptor(_, _, _, _, _, _))
649             .WillByDefault(Invoke([this](uint16_t conn_id, uint16_t handle,
650                                          std::vector<uint8_t> value,
651                                          tGATT_WRITE_TYPE /*write_type*/, GATT_WRITE_OP_CB cb,
652                                          void* cb_data) -> void {
653               auto& ascs = peer_devices.at(conn_id)->ascs;
654               uint8_t idx;
655 
656               if (handle == ascs->ctp_ccc) {
657                 value = UINT16_TO_VEC_UINT8(ascs->ctp_ccc_val);
658               } else {
659                 for (idx = 0; idx < max_num_of_ases; idx++) {
660                   if (handle == ascs->sink_ase_ccc[idx] + 1) {
661                     value = UINT16_TO_VEC_UINT8(ascs->sink_ase_ccc_val[idx]);
662                     break;
663                   }
664                   if (handle == ascs->source_ase_char[idx] + 1) {
665                     value = UINT16_TO_VEC_UINT8(ascs->source_ase_ccc_val[idx]);
666                     break;
667                   }
668                 }
669               }
670 
671               if (cb) {
672                 do_in_main_thread(base::BindOnce(
673                         [](GATT_WRITE_OP_CB cb, uint16_t conn_id, uint16_t handle, uint16_t len,
674                            uint8_t* value, void* cb_data) {
675                           cb(conn_id, GATT_SUCCESS, handle, len, value, cb_data);
676                         },
677                         cb, conn_id, handle, value.size(), value.data(), cb_data));
678               }
679             }));
680 
681     global_conn_id = 1;
682     ON_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_DIRECT_CONNECTION, _))
683             .WillByDefault(Invoke([&](tGATT_IF /*client_if*/, const RawAddress& remote_bda,
684                                       bool /*is_direct*/, bool /*opportunistic*/) {
685               InjectConnectedEvent(remote_bda, global_conn_id++);
686             }));
687 
688     ON_CALL(mock_gatt_interface_, Close(_)).WillByDefault(Invoke([&](uint16_t conn_id) {
689       ASSERT_NE(conn_id, GATT_INVALID_CONN_ID);
690       InjectDisconnectedEvent(conn_id);
691     }));
692 
693     // default Characteristic read handler dispatches requests to service mocks
694     ON_CALL(mock_gatt_queue_, ReadCharacteristic(_, _, _, _))
695             .WillByDefault(Invoke([&](uint16_t conn_id, uint16_t handle, GATT_READ_OP_CB cb,
696                                       void* cb_data) {
697               do_in_main_thread(base::BindOnce(
698                       [](std::map<uint16_t, std::unique_ptr<NiceMock<MockDeviceWrapper>>>*
699                                  peer_devices,
700                          uint16_t conn_id, uint16_t handle, GATT_READ_OP_CB cb,
701                          void* cb_data) -> void {
702                         if (peer_devices->count(conn_id)) {
703                           auto& device = peer_devices->at(conn_id);
704                           auto svc = std::find_if(device->services.begin(), device->services.end(),
705                                                   [handle](const gatt::Service& svc) {
706                                                     return (handle >= svc.handle) &&
707                                                            (handle <= svc.end_handle);
708                                                   });
709                           if (svc == device->services.end()) {
710                             return;
711                           }
712 
713                           GattStatus status;
714                           std::vector<uint8_t> value;
715                           // Dispatch to mockable handler functions
716                           if (svc->handle == device->csis->start) {
717                             std::tie(status, value) =
718                                     device->csis->OnGetCharacteristicValue(handle);
719                           } else if (svc->handle == device->cas->start) {
720                             std::tie(status, value) = device->cas->OnGetCharacteristicValue(handle);
721                           } else if (svc->handle == device->ascs->start) {
722                             std::tie(status, value) =
723                                     device->ascs->OnGetCharacteristicValue(handle);
724                           } else if (svc->handle == device->pacs->start) {
725                             std::tie(status, value) =
726                                     device->pacs->OnGetCharacteristicValue(handle);
727                           } else {
728                             return;
729                           }
730 
731                           cb(conn_id, status, handle, value.size(), value.data(), cb_data);
732                         }
733                       },
734                       &peer_devices, conn_id, handle, cb, cb_data));
735             }));
736 
737     // default multiple Characteristic read handler dispatches requests to service mocks
738     ON_CALL(mock_gatt_queue_, ReadMultiCharacteristic(_, _, _, _))
739             .WillByDefault(Invoke([&](uint16_t conn_id, tBTA_GATTC_MULTI& handles,
740                                       GATT_READ_MULTI_OP_CB cb, void* cb_data) {
741               do_in_main_thread(base::BindOnce(
742                       [](std::map<uint16_t, std::unique_ptr<NiceMock<MockDeviceWrapper>>>*
743                                  peer_devices,
744                          uint16_t conn_id, tBTA_GATTC_MULTI handles, GATT_READ_MULTI_OP_CB cb,
745                          void* cb_data) -> void {
746                         if (!peer_devices->count(conn_id)) {
747                           return;
748                         }
749                         auto& device = peer_devices->at(conn_id);
750 
751                         auto get_char_value_helper = [&](NiceMock<MockDeviceWrapper>& device,
752                                                          uint16_t handle) {
753                           auto svc = std::find_if(device.services.begin(), device.services.end(),
754                                                   [handle](const gatt::Service& svc) {
755                                                     return (handle >= svc.handle) &&
756                                                            (handle <= svc.end_handle);
757                                                   });
758                           if (svc == device.services.end()) {
759                             return std::make_pair(GATT_ERROR, std::vector<uint8_t>());
760                           }
761 
762                           // Dispatch to mockable handler functions
763                           if (svc->handle == device.csis->start) {
764                             return device.csis->OnGetCharacteristicValue(handle);
765                           } else if (svc->handle == device.cas->start) {
766                             return device.cas->OnGetCharacteristicValue(handle);
767                           } else if (svc->handle == device.ascs->start) {
768                             return device.ascs->OnGetCharacteristicValue(handle);
769                           } else if (svc->handle == device.pacs->start) {
770                             return device.pacs->OnGetCharacteristicValue(handle);
771                           } else {
772                             return std::make_pair(GATT_ERROR, std::vector<uint8_t>());
773                           };
774                         };
775                         std::array<uint8_t, GATT_MAX_ATTR_LEN> value;
776                         uint16_t value_end = 0;
777                         for (int i = 0; i < handles.num_attr; i++) {
778                           GattStatus status;
779                           std::vector<uint8_t> curr_val;
780                           std::tie(status, curr_val) =
781                                   get_char_value_helper(*device, handles.handles[i]);
782 
783                           if (status != GATT_SUCCESS) {
784                             cb(conn_id, status, handles, 0, value.data(), cb_data);
785                             return;
786                           }
787 
788                           value[value_end] = (curr_val.size() & 0x00ff);
789                           value[value_end + 1] = (curr_val.size() & 0xff00) >> 8;
790                           value_end += 2;
791 
792                           // concatenate all read values together
793                           std::copy(curr_val.begin(), curr_val.end(), value.data() + value_end);
794                           value_end += curr_val.size();
795                         }
796                         cb(conn_id, GATT_SUCCESS, handles, value_end, value.data(), cb_data);
797                       },
798                       &peer_devices, conn_id, handles, cb, cb_data));
799             }));
800   }
801 
SetUpMockGroups()802   void SetUpMockGroups() {
803     MockCsisClient::SetMockInstanceForTesting(&mock_csis_client_module_);
804     MockDeviceGroups::SetMockInstanceForTesting(&mock_groups_module_);
805     MockLeAudioGroupStateMachine::SetMockInstanceForTesting(&mock_state_machine_);
806 
807     ON_CALL(mock_csis_client_module_, Get()).WillByDefault(Return(&mock_csis_client_module_));
808 
809     // Store group callbacks so that we could inject grouping events
810     group_callbacks_ = nullptr;
811     ON_CALL(mock_groups_module_, Initialize(_)).WillByDefault(SaveArg<0>(&group_callbacks_));
812 
813     ON_CALL(mock_groups_module_, GetGroupId(_, _))
814             .WillByDefault([this](const RawAddress& addr, bluetooth::Uuid /*uuid*/) {
815               if (groups.find(addr) != groups.end()) {
816                 return groups.at(addr);
817               }
818               return bluetooth::groups::kGroupUnknown;
819             });
820 
821     ON_CALL(mock_groups_module_, RemoveDevice(_, _))
822             .WillByDefault([this](const RawAddress& addr, int /*group_id*/) {
823               int group_id = -1;
824               if (groups.find(addr) != groups.end()) {
825                 group_id = groups[addr];
826                 groups.erase(addr);
827               }
828               if (group_id < 0) {
829                 return;
830               }
831 
832               do_in_main_thread(base::BindOnce(
833                       [](const RawAddress& address, int group_id,
834                          bluetooth::groups::DeviceGroupsCallbacks* group_callbacks) {
835                         group_callbacks->OnGroupMemberRemoved(address, group_id);
836                       },
837                       addr, group_id, base::Unretained(group_callbacks_)));
838             });
839 
840     // Our test devices have unique LSB - use it for unique grouping when
841     // devices added with a non-CIS context and no grouping info
842     ON_CALL(mock_groups_module_, AddDevice(_, bluetooth::le_audio::uuid::kCapServiceUuid, _))
843             .WillByDefault(
844                     [this](const RawAddress& addr,
845                            bluetooth::Uuid /*uuid*/ = bluetooth::le_audio::uuid::kCapServiceUuid,
846                            int group_id = bluetooth::groups::kGroupUnknown) -> int {
847                       if (group_id == bluetooth::groups::kGroupUnknown) {
848                         /* Generate group id from address */
849                         groups[addr] = addr.address[RawAddress::kLength - 1];
850                         group_id = groups[addr];
851                       } else {
852                         groups[addr] = group_id;
853                       }
854 
855                       InjectGroupDeviceAdded(addr, groups[addr]);
856                       return addr.address[RawAddress::kLength - 1];
857                     });
858 
859     ON_CALL(mock_state_machine_, Initialize(_))
860             .WillByDefault(SaveArg<0>(&state_machine_callbacks_));
861 
862     ON_CALL(mock_state_machine_, ConfigureStream(_, _, _, _, _))
863             .WillByDefault([this](LeAudioDeviceGroup* group, types::LeAudioContextType context_type,
864                                   types::BidirectionalPair<types::AudioContexts>
865                                           metadata_context_types,
866                                   types::BidirectionalPair<std::vector<uint8_t>> ccid_lists,
867                                   bool configure_qos) {
868               auto group_state = group->GetState();
869               bool isReconfiguration = group->IsPendingConfiguration();
870 
871               log::info(
872                       "ConfigureStream: group {} state {}, context type {} sink metadata_ctx {}, "
873                       "source metadata_ctx {}, ccid_sink size {}, ccid_source_size {}, "
874                       "isReconfiguration {}",
875                       group->group_id_, bluetooth::common::ToString(group_state),
876                       bluetooth::common::ToString(context_type),
877                       bluetooth::common::ToString(metadata_context_types.sink),
878                       bluetooth::common::ToString(metadata_context_types.source),
879                       ccid_lists.sink.size(), ccid_lists.source.size(), isReconfiguration);
880 
881               /* Do what ReleaseCisIds(group) does: start */
882               LeAudioDevice* leAudioDevice = group->GetFirstDevice();
883               while (leAudioDevice != nullptr) {
884                 for (auto& ase : leAudioDevice->ases_) {
885                   ase.cis_id = bluetooth::le_audio::kInvalidCisId;
886                 }
887                 leAudioDevice = group->GetNextDevice(leAudioDevice);
888               }
889               group->ClearAllCises();
890               /* end */
891 
892               if (!group->Configure(context_type, metadata_context_types, ccid_lists)) {
893                 log::error("ConfigureStream: Could not configure ASEs for group {} content type {}",
894                            group->group_id_, int(context_type));
895 
896                 return false;
897               }
898 
899               group->cig.GenerateCisIds(context_type);
900 
901               types::AseState config_state =
902                       types::AseState::BTA_LE_AUDIO_ASE_STATE_CODEC_CONFIGURED;
903 
904               if (configure_qos) {
905                 // Make sure CIG is created
906                 config_state = types::AseState::BTA_LE_AUDIO_ASE_STATE_QOS_CONFIGURED;
907                 group->cig.SetState(types::CigState::CREATED);
908               }
909 
910               for (LeAudioDevice* device = group->GetFirstDevice(); device != nullptr;
911                    device = group->GetNextDevice(device)) {
912                 if (!group->cig.AssignCisIds(device)) {
913                   continue;
914                 }
915 
916                 if (group->cig.GetState() == types::CigState::CREATED) {
917                   group->AssignCisConnHandlesToAses(device);
918                 }
919 
920                 for (auto& ase : device->ases_) {
921                   if (!ase.active) {
922                     continue;
923                   }
924 
925                   ase.cis_state = types::CisState::IDLE;
926                   ase.data_path_state = types::DataPathState::IDLE;
927                   ase.state = config_state;
928                 }
929               }
930 
931               // Inject the state
932               group->SetTargetState(config_state);
933               group->SetState(group->GetTargetState());
934               group->ClearPendingConfiguration();
935               do_in_main_thread(base::BindOnce(
936                       [](int group_id, bluetooth::le_audio::LeAudioGroupStateMachine::Callbacks*
937                                                state_machine_callbacks) {
938                         state_machine_callbacks->StatusReportCb(
939                                 group_id, GroupStreamStatus::CONFIGURED_BY_USER);
940                       },
941                       group->group_id_, base::Unretained(this->state_machine_callbacks_)));
942               return true;
943             });
944 
945     ON_CALL(mock_state_machine_, AttachToStream(_, _, _))
946             .WillByDefault([this](LeAudioDeviceGroup* group, LeAudioDevice* leAudioDevice,
947                                   types::BidirectionalPair<std::vector<uint8_t>> ccids) {
948               log::info(
949                       "AttachToStream: group_id {}, address {}, current_state {}, target_state {}",
950                       group->group_id_, leAudioDevice->address_,
951                       bluetooth::common::ToString(group->GetState()),
952                       bluetooth::common::ToString(group->GetTargetState()));
953 
954               if (group->GetState() != types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING) {
955                 if (group->GetTargetState() == types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING) {
956                   attach_to_stream_scheduled = true;
957                 }
958 
959                 return false;
960               }
961 
962               group->Configure(group->GetConfigurationContextType(), group->GetMetadataContexts(),
963                                ccids);
964               if (!group->cig.AssignCisIds(leAudioDevice)) {
965                 return false;
966               }
967               group->AssignCisConnHandlesToAses(leAudioDevice);
968 
969               auto* stream_conf = &group->stream_conf;
970 
971               for (auto& ase : leAudioDevice->ases_) {
972                 if (!ase.active) {
973                   continue;
974                 }
975 
976                 // And also skip the ase establishment procedure which should
977                 // be tested as part of the state machine unit tests
978                 ase.cis_state = types::CisState::CONNECTED;
979                 ase.data_path_state = types::DataPathState::CONFIGURED;
980                 ase.state = types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING;
981 
982                 uint16_t cis_conn_hdl = ase.cis_conn_hdl;
983                 auto core_config = ase.codec_config.GetAsCoreCodecConfig();
984 
985                 /* Copied from state_machine.cc ProcessHciNotifSetupIsoDataPath */
986                 if (ase.direction == bluetooth::le_audio::types::kLeAudioDirectionSource) {
987                   auto iter = std::find_if(
988                           stream_conf->stream_params.source.stream_locations.begin(),
989                           stream_conf->stream_params.source.stream_locations.end(),
990                           [cis_conn_hdl](auto& pair) { return cis_conn_hdl == pair.first; });
991 
992                   if (iter == stream_conf->stream_params.source.stream_locations.end()) {
993                     stream_conf->stream_params.source.stream_locations.emplace_back(std::make_pair(
994                             ase.cis_conn_hdl, *core_config.audio_channel_allocation));
995 
996                     stream_conf->stream_params.source.num_of_devices++;
997                     stream_conf->stream_params.source.num_of_channels += ase.channel_count;
998 
999                     log::info(
1000                             "AttachToStream: Added Source Stream Configuration. CIS Connection "
1001                             "Handle: "
1002                             "{}, Audio Channel Allocation: {}, Source Number Of "
1003                             "Devices: {}, Source Number Of Channels: {}",
1004                             ase.cis_conn_hdl, *core_config.audio_channel_allocation,
1005                             stream_conf->stream_params.source.num_of_devices,
1006                             stream_conf->stream_params.source.num_of_channels);
1007                   }
1008                 } else {
1009                   auto iter = std::find_if(
1010                           stream_conf->stream_params.sink.stream_locations.begin(),
1011                           stream_conf->stream_params.sink.stream_locations.end(),
1012                           [cis_conn_hdl](auto& pair) { return cis_conn_hdl == pair.first; });
1013 
1014                   if (iter == stream_conf->stream_params.sink.stream_locations.end()) {
1015                     stream_conf->stream_params.sink.stream_locations.emplace_back(std::make_pair(
1016                             ase.cis_conn_hdl, *core_config.audio_channel_allocation));
1017 
1018                     stream_conf->stream_params.sink.num_of_devices++;
1019                     stream_conf->stream_params.sink.num_of_channels += ase.channel_count;
1020 
1021                     log::info(
1022                             "AttachToStream: Added Sink Stream Configuration. CIS Connection "
1023                             "Handle: "
1024                             "{}, Audio Channel Allocation: {}, Sink Number Of Devices: "
1025                             "{}, Sink Number Of Channels: {}",
1026                             ase.cis_conn_hdl, *core_config.audio_channel_allocation,
1027                             stream_conf->stream_params.sink.num_of_devices,
1028                             stream_conf->stream_params.sink.num_of_channels);
1029                   }
1030                 }
1031               }
1032 
1033               return true;
1034             });
1035 
1036     ON_CALL(mock_state_machine_, StartStream(_, _, _, _))
1037             .WillByDefault([this](LeAudioDeviceGroup* group, types::LeAudioContextType context_type,
1038                                   types::BidirectionalPair<types::AudioContexts>
1039                                           metadata_context_types,
1040                                   types::BidirectionalPair<std::vector<uint8_t>> ccid_lists) {
1041               auto group_state = group->GetState();
1042               log::info(
1043                       "StartStream: group {} state {}, context type {} sink metadata_ctx {}, "
1044                       "source metadata_ctx {}, ccid_sink size {}, ccid_source_size {}",
1045                       group->group_id_, bluetooth::common::ToString(group_state),
1046                       bluetooth::common::ToString(context_type),
1047                       bluetooth::common::ToString(metadata_context_types.sink),
1048                       bluetooth::common::ToString(metadata_context_types.source),
1049                       ccid_lists.sink.size(), ccid_lists.source.size());
1050 
1051               /* Do nothing if already streaming - the implementation would
1052                * probably update the metadata.
1053                */
1054               if (group_state == types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING) {
1055                 return true;
1056               }
1057 
1058               // Inject the state
1059               group->SetTargetState(types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
1060 
1061               if (group_state != types::AseState::BTA_LE_AUDIO_ASE_STATE_QOS_CONFIGURED) {
1062                 /* Do what ReleaseCisIds(group) does: start */
1063                 LeAudioDevice* leAudioDevice = group->GetFirstDevice();
1064                 while (leAudioDevice != nullptr) {
1065                   for (auto& ase : leAudioDevice->ases_) {
1066                     ase.cis_id = bluetooth::le_audio::kInvalidCisId;
1067                   }
1068                   leAudioDevice = group->GetNextDevice(leAudioDevice);
1069                 }
1070                 group->ClearAllCises();
1071                 /* end */
1072 
1073                 if (!group->Configure(context_type, metadata_context_types, ccid_lists)) {
1074                   log::error("StartStream: failed to set ASE configuration");
1075                   return false;
1076                 }
1077 
1078                 if (group_state == types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE ||
1079                     group_state == types::AseState::BTA_LE_AUDIO_ASE_STATE_CODEC_CONFIGURED) {
1080                   group->cig.GenerateCisIds(context_type);
1081 
1082                   std::vector<uint16_t> conn_handles;
1083                   for (uint8_t i = 0; i < (uint8_t)(group->cig.cises.size()); i++) {
1084                     conn_handles.push_back(iso_con_counter_++);
1085                   }
1086                   group->cig.AssignCisConnHandles(conn_handles);
1087                   for (LeAudioDevice* device = group->GetFirstActiveDevice(); device != nullptr;
1088                        device = group->GetNextActiveDevice(device)) {
1089                     if (!group->cig.AssignCisIds(device)) {
1090                       return false;
1091                     }
1092                     group->AssignCisConnHandlesToAses(device);
1093                   }
1094                 }
1095               }
1096 
1097               auto* stream_conf = &group->stream_conf;
1098 
1099               // Fake ASE configuration
1100               for (LeAudioDevice* device = group->GetFirstActiveDevice(); device != nullptr;
1101                    device = group->GetNextActiveDevice(device)) {
1102                 for (auto& ase : device->ases_) {
1103                   if (!ase.active) {
1104                     continue;
1105                   }
1106 
1107                   // And also skip the ase establishment procedure which should
1108                   // be tested as part of the state machine unit tests
1109                   ase.cis_state = types::CisState::CONNECTED;
1110                   ase.data_path_state = types::DataPathState::CONFIGURED;
1111                   ase.state = types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING;
1112                   ase.qos_preferences.pres_delay_min = 2500;
1113                   ase.qos_preferences.pres_delay_max = 2500;
1114                   ase.qos_preferences.preferred_pres_delay_min = 2500;
1115                   ase.qos_preferences.preferred_pres_delay_max = 2500;
1116                   auto core_config = ase.codec_config.GetAsCoreCodecConfig();
1117 
1118                   uint16_t cis_conn_hdl = ase.cis_conn_hdl;
1119 
1120                   /* Copied from state_machine.cc ProcessHciNotifSetupIsoDataPath */
1121                   if (ase.direction == bluetooth::le_audio::types::kLeAudioDirectionSource) {
1122                     auto iter = std::find_if(
1123                             stream_conf->stream_params.source.stream_locations.begin(),
1124                             stream_conf->stream_params.source.stream_locations.end(),
1125                             [cis_conn_hdl](auto& pair) { return cis_conn_hdl == pair.first; });
1126 
1127                     if (iter == stream_conf->stream_params.source.stream_locations.end()) {
1128                       stream_conf->stream_params.source.stream_locations.emplace_back(
1129                               std::make_pair(ase.cis_conn_hdl,
1130                                              *core_config.audio_channel_allocation));
1131 
1132                       stream_conf->stream_params.source.num_of_devices++;
1133                       stream_conf->stream_params.source.num_of_channels += ase.channel_count;
1134                       stream_conf->stream_params.source.audio_channel_allocation |=
1135                               *core_config.audio_channel_allocation;
1136 
1137                       if (stream_conf->stream_params.source.sample_frequency_hz == 0) {
1138                         stream_conf->stream_params.source.sample_frequency_hz =
1139                                 core_config.GetSamplingFrequencyHz();
1140                       } else {
1141                         log::assert_that(stream_conf->stream_params.source.sample_frequency_hz ==
1142                                                  core_config.GetSamplingFrequencyHz(),
1143                                          "StartStream: sample freq mismatch: {}!={}",
1144                                          stream_conf->stream_params.source.sample_frequency_hz,
1145                                          core_config.GetSamplingFrequencyHz());
1146                       }
1147 
1148                       if (stream_conf->stream_params.source.octets_per_codec_frame == 0) {
1149                         stream_conf->stream_params.source.octets_per_codec_frame =
1150                                 *core_config.octets_per_codec_frame;
1151                       } else {
1152                         log::assert_that(stream_conf->stream_params.source.octets_per_codec_frame ==
1153                                                  *core_config.octets_per_codec_frame,
1154                                          "StartStream: octets per frame mismatch: {}!={}",
1155                                          stream_conf->stream_params.source.octets_per_codec_frame,
1156                                          *core_config.octets_per_codec_frame);
1157                       }
1158 
1159                       if (stream_conf->stream_params.source.codec_frames_blocks_per_sdu == 0) {
1160                         stream_conf->stream_params.source.codec_frames_blocks_per_sdu =
1161                                 *core_config.codec_frames_blocks_per_sdu;
1162                         stream_conf->stream_params.source.frame_duration_us =
1163                                 core_config.GetFrameDurationUs();
1164                       } else {
1165                         log::assert_that(
1166                                 stream_conf->stream_params.source.codec_frames_blocks_per_sdu ==
1167                                         *core_config.codec_frames_blocks_per_sdu,
1168                                 "StartStream: codec_frames_blocks_per_sdu: {}!={}",
1169                                 stream_conf->stream_params.source.codec_frames_blocks_per_sdu,
1170                                 *core_config.codec_frames_blocks_per_sdu);
1171                       }
1172 
1173                       log::info(
1174                               "StartStream: Added Source Stream Configuration. CIS Connection "
1175                               "Handle: {}, Audio Channel Allocation: {}, Source Number "
1176                               "Of Devices: {}, Source Number Of Channels: {}",
1177                               ase.cis_conn_hdl, *core_config.audio_channel_allocation,
1178                               stream_conf->stream_params.source.num_of_devices,
1179                               stream_conf->stream_params.source.num_of_channels);
1180                     }
1181                   } else {
1182                     auto iter = std::find_if(
1183                             stream_conf->stream_params.sink.stream_locations.begin(),
1184                             stream_conf->stream_params.sink.stream_locations.end(),
1185                             [cis_conn_hdl](auto& pair) { return cis_conn_hdl == pair.first; });
1186 
1187                     if (iter == stream_conf->stream_params.sink.stream_locations.end()) {
1188                       stream_conf->stream_params.sink.stream_locations.emplace_back(std::make_pair(
1189                               ase.cis_conn_hdl, *core_config.audio_channel_allocation));
1190 
1191                       stream_conf->stream_params.sink.num_of_devices++;
1192                       stream_conf->stream_params.sink.num_of_channels += ase.channel_count;
1193 
1194                       stream_conf->stream_params.sink.audio_channel_allocation |=
1195                               *core_config.audio_channel_allocation;
1196 
1197                       if (stream_conf->stream_params.sink.sample_frequency_hz == 0) {
1198                         stream_conf->stream_params.sink.sample_frequency_hz =
1199                                 core_config.GetSamplingFrequencyHz();
1200                       } else {
1201                         log::assert_that(stream_conf->stream_params.sink.sample_frequency_hz ==
1202                                                  core_config.GetSamplingFrequencyHz(),
1203                                          "StartStream: sample freq mismatch: {}!={}",
1204                                          stream_conf->stream_params.sink.sample_frequency_hz,
1205                                          core_config.GetSamplingFrequencyHz());
1206                       }
1207 
1208                       if (stream_conf->stream_params.sink.octets_per_codec_frame == 0) {
1209                         stream_conf->stream_params.sink.octets_per_codec_frame =
1210                                 *core_config.octets_per_codec_frame;
1211                       } else {
1212                         log::assert_that(stream_conf->stream_params.sink.octets_per_codec_frame ==
1213                                                  *core_config.octets_per_codec_frame,
1214                                          "StartStream: octets per frame mismatch: {}!={}",
1215                                          stream_conf->stream_params.sink.octets_per_codec_frame,
1216                                          *core_config.octets_per_codec_frame);
1217                       }
1218 
1219                       if (stream_conf->stream_params.sink.codec_frames_blocks_per_sdu == 0) {
1220                         stream_conf->stream_params.sink.codec_frames_blocks_per_sdu =
1221                                 *core_config.codec_frames_blocks_per_sdu;
1222                         stream_conf->stream_params.sink.frame_duration_us =
1223                                 core_config.GetFrameDurationUs();
1224                       } else {
1225                         log::assert_that(
1226                                 stream_conf->stream_params.sink.codec_frames_blocks_per_sdu ==
1227                                         *core_config.codec_frames_blocks_per_sdu,
1228                                 "StartStream: codec_frames_blocks_per_sdu: {}!={}",
1229                                 stream_conf->stream_params.sink.codec_frames_blocks_per_sdu,
1230                                 *core_config.codec_frames_blocks_per_sdu);
1231                       }
1232 
1233                       log::info(
1234                               "StartStream: Added Sink Stream Configuration. CIS Connection "
1235                               "Handle: "
1236                               "{}, Audio Channel Allocation: {}, Sink Number Of "
1237                               "Devices: {}, Sink Number Of Channels: {}",
1238                               ase.cis_conn_hdl, *core_config.audio_channel_allocation,
1239                               stream_conf->stream_params.sink.num_of_devices,
1240                               stream_conf->stream_params.sink.num_of_channels);
1241                     }
1242                   }
1243                 }
1244                 group->SetState(types::AseState::BTA_LE_AUDIO_ASE_STATE_QOS_CONFIGURED);
1245                 /* Assume CIG is created */
1246                 group->cig.SetState(bluetooth::le_audio::types::CigState::CREATED);
1247               }
1248 
1249               streaming_groups[group->group_id_] = group;
1250 
1251               if (stay_at_qos_config_in_start_stream) {
1252                 return true;
1253               }
1254 
1255               group->SetState(types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
1256               do_in_main_thread(base::BindOnce(
1257                       [](int group_id, bluetooth::le_audio::LeAudioGroupStateMachine::Callbacks*
1258                                                state_machine_callbacks) {
1259                         state_machine_callbacks->StatusReportCb(group_id,
1260                                                                 GroupStreamStatus::STREAMING);
1261                       },
1262                       group->group_id_, base::Unretained(this->state_machine_callbacks_)));
1263               return true;
1264             });
1265 
1266     ON_CALL(mock_state_machine_, SuspendStream(_)).WillByDefault([this](LeAudioDeviceGroup* group) {
1267       // Fake ASE state
1268       for (LeAudioDevice* device = group->GetFirstDevice(); device != nullptr;
1269            device = group->GetNextDevice(device)) {
1270         for (auto& ase : device->ases_) {
1271           ase.cis_state = types::CisState::CONNECTED;
1272           ase.state = types::AseState::BTA_LE_AUDIO_ASE_STATE_QOS_CONFIGURED;
1273         }
1274       }
1275 
1276       // Inject the state
1277       group->SetTargetState(types::AseState::BTA_LE_AUDIO_ASE_STATE_QOS_CONFIGURED);
1278       group->SetState(group->GetTargetState());
1279       state_machine_callbacks_->StatusReportCb(group->group_id_, GroupStreamStatus::SUSPENDED);
1280     });
1281 
1282     ON_CALL(mock_state_machine_, ProcessHciNotifAclDisconnected(_, _))
1283             .WillByDefault([this](LeAudioDeviceGroup* group, LeAudioDevice* leAudioDevice) {
1284               if (!group) {
1285                 return;
1286               }
1287 
1288               for (auto& ase : leAudioDevice->ases_) {
1289                 group->RemoveCisFromStreamIfNeeded(leAudioDevice, ase.cis_conn_hdl);
1290               }
1291 
1292               if (group->IsEmpty()) {
1293                 group->cig.SetState(bluetooth::le_audio::types::CigState::NONE);
1294                 InjectCigRemoved(group->group_id_);
1295               }
1296             });
1297 
1298     ON_CALL(mock_state_machine_, ProcessHciNotifCisDisconnected(_, _, _))
1299             .WillByDefault([](LeAudioDeviceGroup* group, LeAudioDevice* leAudioDevice,
1300                               const bluetooth::hci::iso_manager::cis_disconnected_evt* event) {
1301               if (!group) {
1302                 return;
1303               }
1304               auto ases_pair = leAudioDevice->GetAsesByCisConnHdl(event->cis_conn_hdl);
1305               if (ases_pair.sink) {
1306                 ases_pair.sink->cis_state = types::CisState::ASSIGNED;
1307                 ases_pair.sink->active = false;
1308               }
1309               if (ases_pair.source) {
1310                 ases_pair.source->active = false;
1311                 ases_pair.source->cis_state = types::CisState::ASSIGNED;
1312               }
1313               /* Invalidate stream configuration if needed */
1314               auto* stream_conf = &group->stream_conf;
1315               if (!stream_conf->stream_params.sink.stream_locations.empty() ||
1316                   !stream_conf->stream_params.source.stream_locations.empty()) {
1317                 stream_conf->stream_params.sink.stream_locations.erase(
1318                         std::remove_if(
1319                                 stream_conf->stream_params.sink.stream_locations.begin(),
1320                                 stream_conf->stream_params.sink.stream_locations.end(),
1321                                 [leAudioDevice, &stream_conf](auto& pair) {
1322                                   auto ases = leAudioDevice->GetAsesByCisConnHdl(pair.first);
1323 
1324                                   log::info(
1325                                           ", sink ase to delete. Cis handle: {}, ase pointer: "
1326                                           "{}",
1327                                           (int)(pair.first), std::format_ptr(+ases.sink));
1328                                   if (ases.sink) {
1329                                     stream_conf->stream_params.sink.num_of_devices--;
1330                                     stream_conf->stream_params.sink.num_of_channels -=
1331                                             ases.sink->channel_count;
1332 
1333                                     log::info(
1334                                             "Sink Number Of Devices: {}, Sink Number Of "
1335                                             "Channels: {}",
1336                                             stream_conf->stream_params.sink.num_of_devices,
1337                                             stream_conf->stream_params.sink.num_of_channels);
1338                                   }
1339                                   return ases.sink;
1340                                 }),
1341                         stream_conf->stream_params.sink.stream_locations.end());
1342 
1343                 stream_conf->stream_params.source.stream_locations.erase(
1344                         std::remove_if(
1345                                 stream_conf->stream_params.source.stream_locations.begin(),
1346                                 stream_conf->stream_params.source.stream_locations.end(),
1347                                 [leAudioDevice, &stream_conf](auto& pair) {
1348                                   auto ases = leAudioDevice->GetAsesByCisConnHdl(pair.first);
1349 
1350                                   log::info(", source to delete. Cis handle: {}, ase pointer: {}",
1351                                             (int)(pair.first), std::format_ptr(ases.source));
1352                                   if (ases.source) {
1353                                     stream_conf->stream_params.source.num_of_devices--;
1354                                     stream_conf->stream_params.source.num_of_channels -=
1355                                             ases.source->channel_count;
1356 
1357                                     log::info(
1358                                             ", Source Number Of Devices: {}, Source Number Of "
1359                                             "Channels: {}",
1360                                             stream_conf->stream_params.source.num_of_devices,
1361                                             stream_conf->stream_params.source.num_of_channels);
1362                                   }
1363                                   return ases.source;
1364                                 }),
1365                         stream_conf->stream_params.source.stream_locations.end());
1366               }
1367 
1368               group->cig.UnassignCis(leAudioDevice, event->cis_conn_hdl);
1369             });
1370 
1371     ON_CALL(mock_state_machine_, StopStream(_)).WillByDefault([this](LeAudioDeviceGroup* group) {
1372       for (LeAudioDevice* device = group->GetFirstDevice(); device != nullptr;
1373            device = group->GetNextDevice(device)) {
1374         /* Invalidate stream configuration if needed */
1375         auto* stream_conf = &group->stream_conf;
1376         if (!stream_conf->stream_params.sink.stream_locations.empty() ||
1377             !stream_conf->stream_params.source.stream_locations.empty()) {
1378           stream_conf->stream_params.sink.stream_locations.erase(
1379                   std::remove_if(stream_conf->stream_params.sink.stream_locations.begin(),
1380                                  stream_conf->stream_params.sink.stream_locations.end(),
1381                                  [device, &stream_conf](auto& pair) {
1382                                    auto ases = device->GetAsesByCisConnHdl(pair.first);
1383 
1384                                    log::info(
1385                                            ", sink ase to delete. Cis handle: {}, ase "
1386                                            "pointer: {}",
1387                                            (int)(pair.first), std::format_ptr(+ases.sink));
1388                                    if (ases.sink) {
1389                                      stream_conf->stream_params.sink.num_of_devices--;
1390                                      stream_conf->stream_params.sink.num_of_channels -=
1391                                              ases.sink->channel_count;
1392 
1393                                      log::info(
1394                                              "Sink Number Of Devices: {}, Sink Number Of "
1395                                              "Channels: {}",
1396                                              stream_conf->stream_params.sink.num_of_devices,
1397                                              stream_conf->stream_params.sink.num_of_channels);
1398                                    }
1399                                    return ases.sink;
1400                                  }),
1401                   stream_conf->stream_params.sink.stream_locations.end());
1402 
1403           stream_conf->stream_params.source.stream_locations.erase(
1404                   std::remove_if(stream_conf->stream_params.source.stream_locations.begin(),
1405                                  stream_conf->stream_params.source.stream_locations.end(),
1406                                  [device, &stream_conf](auto& pair) {
1407                                    auto ases = device->GetAsesByCisConnHdl(pair.first);
1408 
1409                                    log::info(
1410                                            ", source to delete. Cis handle: {}, ase pointer: "
1411                                            "{}",
1412                                            (int)(pair.first), std::format_ptr(+ases.source));
1413                                    if (ases.source) {
1414                                      stream_conf->stream_params.source.num_of_devices--;
1415                                      stream_conf->stream_params.source.num_of_channels -=
1416                                              ases.source->channel_count;
1417 
1418                                      log::info(
1419                                              ", Source Number Of Devices: {}, Source Number "
1420                                              "Of Channels: {}",
1421                                              stream_conf->stream_params.source.num_of_devices,
1422                                              stream_conf->stream_params.source.num_of_channels);
1423                                    }
1424                                    return ases.source;
1425                                  }),
1426                   stream_conf->stream_params.source.stream_locations.end());
1427         }
1428 
1429         for (auto& ase : device->ases_) {
1430           group->cig.UnassignCis(device, ase.cis_conn_hdl);
1431 
1432           ase.cis_state = types::CisState::IDLE;
1433           ase.data_path_state = types::DataPathState::IDLE;
1434           ase.active = false;
1435           ase.state = types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE;
1436           ase.cis_id = 0;
1437           ase.cis_conn_hdl = bluetooth::le_audio::kInvalidCisConnHandle;
1438         }
1439       }
1440 
1441       // Inject the state
1442       group->SetTargetState(types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE);
1443       group->SetState(types::AseState::BTA_LE_AUDIO_ASE_STATE_RELEASING);
1444       state_machine_callbacks_->StatusReportCb(group->group_id_, GroupStreamStatus::RELEASING);
1445 
1446       if (stay_at_releasing_stop_stream) {
1447         log::info("StopStream {} -> stay in Releasing state", group->group_id_);
1448         return;
1449       }
1450       group->SetState(group->GetTargetState());
1451 
1452       do_in_main_thread(base::BindOnce(
1453               [](bluetooth::le_audio::LeAudioGroupStateMachine::Callbacks* cb, int group_id) {
1454                 cb->StatusReportCb(group_id, GroupStreamStatus::IDLE);
1455               },
1456               state_machine_callbacks_, group->group_id_));
1457     });
1458   }
1459 
SetUp()1460   void SetUp() override {
1461     __android_log_set_minimum_priority(ANDROID_LOG_VERBOSE);
1462     init_message_loop_thread();
1463     reset_mock_function_count_map();
1464     ON_CALL(controller_, SupportsBleConnectedIsochronousStreamCentral).WillByDefault(Return(true));
1465     ON_CALL(controller_, SupportsBleConnectedIsochronousStreamPeripheral)
1466             .WillByDefault(Return(true));
1467     ON_CALL(controller_, SupportsBle2mPhy).WillByDefault(Return(true));
1468     bluetooth::hci::testing::mock_controller_ = &controller_;
1469     bluetooth::manager::SetMockBtmInterface(&mock_btm_interface_);
1470     gatt::SetMockBtaGattInterface(&mock_gatt_interface_);
1471     gatt::SetMockBtaGattQueue(&mock_gatt_queue_);
1472     bluetooth::storage::SetMockBtifStorageInterface(&mock_btif_storage_);
1473 
1474     iso_manager_ = bluetooth::hci::IsoManager::GetInstance();
1475     ASSERT_NE(iso_manager_, nullptr);
1476     iso_manager_->Start();
1477 
1478     mock_iso_manager_ = MockIsoManager::GetInstance();
1479     ON_CALL(*mock_iso_manager_, RegisterCigCallbacks(_)).WillByDefault(SaveArg<0>(&cig_callbacks_));
1480 
1481     ON_CALL(mock_btm_interface_, IsLinkKeyKnown(_, _)).WillByDefault(DoAll(Return(true)));
1482 
1483     // Required since we call OnAudioDataReady()
1484     const auto codec_location = ::bluetooth::le_audio::types::CodecLocation::HOST;
1485 
1486     SetUpMockAudioHal();
1487     SetUpMockGroups();
1488     SetUpMockGatt();
1489     SetUpMockCodecManager(codec_location);
1490 
1491     stay_at_qos_config_in_start_stream = false;
1492     stay_at_releasing_stop_stream = false;
1493 
1494     available_snk_context_types_ = 0xffff;
1495     available_src_context_types_ = 0xffff;
1496     supported_snk_context_types_ = 0xffff;
1497     supported_src_context_types_ = 0xffff;
1498 
1499     empty_source_pack_ = false;
1500     empty_sink_pack_ = false;
1501 
1502     bluetooth::le_audio::AudioSetConfigurationProvider::Initialize(codec_location);
1503     ASSERT_FALSE(LeAudioClient::IsLeAudioClientRunning());
1504   }
1505 
SetUpMockCodecManager(types::CodecLocation location)1506   void SetUpMockCodecManager(types::CodecLocation location) {
1507     codec_manager_ = bluetooth::le_audio::CodecManager::GetInstance();
1508     ASSERT_NE(codec_manager_, nullptr);
1509     std::vector<bluetooth::le_audio::btle_audio_codec_config_t> mock_offloading_preference(0);
1510     codec_manager_->Start(mock_offloading_preference);
1511     mock_codec_manager_ = MockCodecManager::GetInstance();
1512     ASSERT_NE((void*)mock_codec_manager_, (void*)codec_manager_);
1513     ASSERT_NE(mock_codec_manager_, nullptr);
1514     ON_CALL(*mock_codec_manager_, GetCodecLocation()).WillByDefault(Return(location));
1515     ON_CALL(*mock_codec_manager_, UpdateActiveUnicastAudioHalClient(_, _, _))
1516             .WillByDefault(Return(true));
1517     ON_CALL(*mock_codec_manager_, UpdateActiveBroadcastAudioHalClient(_, _))
1518             .WillByDefault(Return(true));
1519     // Turn on the dual bidir SWB support
1520     ON_CALL(*mock_codec_manager_, IsDualBiDirSwbSupported).WillByDefault(Return(true));
1521     // Regardless of the codec location, return all the possible configurations
1522     ON_CALL(*mock_codec_manager_, GetCodecConfig)
1523             .WillByDefault(Invoke([](const CodecManager::UnicastConfigurationRequirements&
1524                                              requirements,
1525                                      CodecManager::UnicastConfigurationProvider provider) {
1526               auto filtered = *le_audio::AudioSetConfigurationProvider::Get()->GetConfigurations(
1527                       requirements.audio_context_type);
1528               // Filter out the dual bidir SWB configurations
1529               if (!bluetooth::le_audio::CodecManager::GetInstance()->IsDualBiDirSwbSupported()) {
1530                 filtered.erase(std::remove_if(filtered.begin(), filtered.end(),
1531                                               [](auto const& el) {
1532                                                 if (el->confs.source.empty()) {
1533                                                   return false;
1534                                                 }
1535                                                 return AudioSetConfigurationProvider::Get()
1536                                                         ->CheckConfigurationIsDualBiDirSwb(*el);
1537                                               }),
1538                                filtered.end());
1539               }
1540               return provider(requirements, &filtered);
1541             }));
1542   }
1543 
TearDown()1544   void TearDown() override {
1545     com::android::bluetooth::flags::provider_->reset_flags();
1546 
1547     if (is_audio_unicast_source_acquired) {
1548       if (unicast_source_hal_cb_ != nullptr) {
1549         EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop).Times(1);
1550       }
1551       EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(1);
1552     }
1553 
1554     if (is_audio_unicast_sink_acquired) {
1555       if (unicast_sink_hal_cb_ != nullptr) {
1556         EXPECT_CALL(*mock_le_audio_sink_hal_client_, Stop).Times(1);
1557       }
1558       EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(1);
1559     }
1560 
1561     // Message loop cleanup should wait for all the 'till now' scheduled calls
1562     // so it should be called right at the very begginning of teardown.
1563     cleanup_message_loop_thread();
1564 
1565     // This is required since Stop() and Cleanup() may trigger some callbacks or
1566     // drop unique pointers to mocks we have raw pointer for and we want to
1567     // verify them all.
1568     Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
1569 
1570     if (LeAudioClient::IsLeAudioClientRunning()) {
1571       EXPECT_CALL(mock_gatt_interface_, AppDeregister(gatt_if)).Times(1);
1572       LeAudioClient::Cleanup();
1573       ASSERT_FALSE(LeAudioClient::IsLeAudioClientRunning());
1574     }
1575 
1576     owned_mock_le_audio_sink_hal_client_.reset();
1577     owned_mock_le_audio_source_hal_client_.reset();
1578 
1579     if (bluetooth::le_audio::AudioSetConfigurationProvider::Get()) {
1580       bluetooth::le_audio::AudioSetConfigurationProvider::Cleanup();
1581     }
1582 
1583     iso_manager_->Stop();
1584     bluetooth::hci::testing::mock_controller_ = nullptr;
1585   }
1586 
1587 protected:
1588   class MockDeviceWrapper {
1589     class IGattHandlers {
1590     public:
1591       // IGattHandlers() = default;
1592       virtual ~IGattHandlers() = default;
1593       virtual std::pair<GattStatus, std::vector<uint8_t>> OnGetCharacteristicValue(
1594               uint16_t handle) = 0;
1595       virtual void OnWriteCharacteristic(uint16_t handle, std::vector<uint8_t> value,
1596                                          tGATT_WRITE_TYPE write_type, GATT_WRITE_OP_CB cb,
1597                                          void* cb_data) = 0;
1598     };
1599 
1600   public:
1601     struct csis_mock : public IGattHandlers {
1602       uint16_t start = 0;
1603       uint16_t end = 0;
1604       uint16_t sirk_char = 0;
1605       uint16_t sirk_ccc = 0;
1606       uint16_t size_char = 0;
1607       uint16_t size_ccc = 0;
1608       uint16_t lock_char = 0;
1609       uint16_t lock_ccc = 0;
1610       uint16_t rank_char = 0;
1611 
1612       int rank = 0;
1613       int size = 0;
1614 
1615       MOCK_METHOD((std::pair<GattStatus, std::vector<uint8_t>>), OnGetCharacteristicValue,
1616                   (uint16_t handle), (override));
1617       MOCK_METHOD((void), OnWriteCharacteristic,
1618                   (uint16_t handle, std::vector<uint8_t> value, tGATT_WRITE_TYPE write_type,
1619                    GATT_WRITE_OP_CB cb, void* cb_data),
1620                   (override));
1621     };
1622 
1623     struct cas_mock : public IGattHandlers {
1624       uint16_t start = 0;
1625       uint16_t end = 0;
1626       uint16_t csis_include = 0;
1627 
1628       MOCK_METHOD((std::pair<GattStatus, std::vector<uint8_t>>), OnGetCharacteristicValue,
1629                   (uint16_t handle), (override));
1630       MOCK_METHOD((void), OnWriteCharacteristic,
1631                   (uint16_t handle, std::vector<uint8_t> value, tGATT_WRITE_TYPE write_type,
1632                    GATT_WRITE_OP_CB cb, void* cb_data),
1633                   (override));
1634     };
1635 
1636     struct pacs_mock : public IGattHandlers {
1637       uint16_t start = 0;
1638       uint16_t sink_pac_char = 0;
1639       uint16_t sink_pac_ccc = 0;
1640       uint16_t sink_audio_loc_char = 0;
1641       uint16_t sink_audio_loc_ccc = 0;
1642       uint16_t source_pac_char = 0;
1643       uint16_t source_pac_ccc = 0;
1644       uint16_t source_audio_loc_char = 0;
1645       uint16_t source_audio_loc_ccc = 0;
1646       uint16_t avail_contexts_char = 0;
1647       uint16_t avail_contexts_ccc = 0;
1648       uint16_t supp_contexts_char = 0;
1649       uint16_t supp_contexts_ccc = 0;
1650       uint16_t end = 0;
1651 
1652       MOCK_METHOD((std::pair<GattStatus, std::vector<uint8_t>>), OnGetCharacteristicValue,
1653                   (uint16_t handle), (override));
1654       MOCK_METHOD((void), OnWriteCharacteristic,
1655                   (uint16_t handle, std::vector<uint8_t> value, tGATT_WRITE_TYPE write_type,
1656                    GATT_WRITE_OP_CB cb, void* cb_data),
1657                   (override));
1658     };
1659 
1660     struct ascs_mock : public IGattHandlers {
1661       uint16_t start = 0;
1662       uint16_t sink_ase_char[max_num_of_ases] = {0};
1663       uint16_t sink_ase_ccc[max_num_of_ases] = {0};
1664       uint16_t sink_ase_ccc_val[max_num_of_ases] = {0};
1665       uint16_t source_ase_char[max_num_of_ases] = {0};
1666       uint16_t source_ase_ccc[max_num_of_ases] = {0};
1667       uint16_t source_ase_ccc_val[max_num_of_ases] = {0};
1668       uint16_t ctp_char = 0;
1669       uint16_t ctp_ccc = 0;
1670       uint16_t ctp_ccc_val = 0;
1671       uint16_t end = 0;
1672 
1673       MOCK_METHOD((std::pair<GattStatus, std::vector<uint8_t>>), OnGetCharacteristicValue,
1674                   (uint16_t handle), (override));
1675       MOCK_METHOD((void), OnWriteCharacteristic,
1676                   (uint16_t handle, std::vector<uint8_t> value, tGATT_WRITE_TYPE write_type,
1677                    GATT_WRITE_OP_CB cb, void* cb_data),
1678                   (override));
1679     };
1680 
MockDeviceWrapper(RawAddress addr,const std::list<gatt::Service> & services,std::unique_ptr<NiceMock<MockDeviceWrapper::csis_mock>> csis,std::unique_ptr<NiceMock<MockDeviceWrapper::cas_mock>> cas,std::unique_ptr<NiceMock<MockDeviceWrapper::ascs_mock>> ascs,std::unique_ptr<NiceMock<MockDeviceWrapper::pacs_mock>> pacs)1681     MockDeviceWrapper(RawAddress addr, const std::list<gatt::Service>& services,
1682                       std::unique_ptr<NiceMock<MockDeviceWrapper::csis_mock>> csis,
1683                       std::unique_ptr<NiceMock<MockDeviceWrapper::cas_mock>> cas,
1684                       std::unique_ptr<NiceMock<MockDeviceWrapper::ascs_mock>> ascs,
1685                       std::unique_ptr<NiceMock<MockDeviceWrapper::pacs_mock>> pacs)
1686         : addr(addr) {
1687       this->services = services;
1688       this->csis = std::move(csis);
1689       this->cas = std::move(cas);
1690       this->ascs = std::move(ascs);
1691       this->pacs = std::move(pacs);
1692     }
1693 
~MockDeviceWrapper()1694     ~MockDeviceWrapper() {
1695       Mock::VerifyAndClearExpectations(csis.get());
1696       Mock::VerifyAndClearExpectations(cas.get());
1697       Mock::VerifyAndClearExpectations(ascs.get());
1698       Mock::VerifyAndClearExpectations(pacs.get());
1699     }
1700 
1701     RawAddress addr;
1702     bool connected = false;
1703 
1704     // A list of services and their useful params
1705     std::list<gatt::Service> services;
1706     std::unique_ptr<csis_mock> csis;
1707     std::unique_ptr<cas_mock> cas;
1708     std::unique_ptr<ascs_mock> ascs;
1709     std::unique_ptr<pacs_mock> pacs;
1710   };
1711 
SyncOnMainLoop()1712   void SyncOnMainLoop() {
1713     // Wait for the main loop to flush
1714     // WARNING: Not tested with Timers pushing periodic tasks to the main loop
1715     while (num_async_tasks > 0) {
1716     }
1717   }
1718 
ConnectLeAudio(const RawAddress & address,bool isEncrypted=true,bool expect_connected_event=true)1719   void ConnectLeAudio(const RawAddress& address, bool isEncrypted = true,
1720                       bool expect_connected_event = true) {
1721     // by default indicate link as encrypted
1722     ON_CALL(mock_btm_interface_, BTM_IsEncrypted(address, _))
1723             .WillByDefault(DoAll(Return(isEncrypted)));
1724 
1725     ON_CALL(mock_btm_interface_, IsLinkKeyKnown(address, _)).WillByDefault(DoAll(Return(true)));
1726 
1727     EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, address, BTM_BLE_DIRECT_CONNECTION, _))
1728             .Times(1);
1729 
1730     /* If connected event is not expected to arrive, don't test those two below
1731      */
1732     if (expect_connected_event) {
1733       EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, address, false));
1734       EXPECT_CALL(mock_gatt_interface_,
1735                   Open(gatt_if, address, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _))
1736               .Times(1);
1737     }
1738 
1739     do_in_main_thread(base::BindOnce(&LeAudioClient::Connect,
1740                                      base::Unretained(LeAudioClient::Get()), address));
1741 
1742     SyncOnMainLoop();
1743     Mock::VerifyAndClearExpectations(&mock_btm_interface_);
1744     Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
1745     Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
1746   }
1747 
DisconnectLeAudioWithGattClose(const RawAddress & address,uint16_t conn_id,tGATT_DISCONN_REASON=GATT_CONN_TERMINATE_LOCAL_HOST)1748   void DisconnectLeAudioWithGattClose(
1749           const RawAddress& address, uint16_t conn_id,
1750           tGATT_DISCONN_REASON /*reason*/ = GATT_CONN_TERMINATE_LOCAL_HOST) {
1751     EXPECT_CALL(mock_audio_hal_client_callbacks_,
1752                 OnConnectionState(ConnectionState::DISCONNECTED, address))
1753             .Times(1);
1754 
1755     // For test purpose use the acl handle same as conn_id
1756     ON_CALL(mock_btm_interface_, GetHCIConnHandle(address, _))
1757             .WillByDefault([conn_id](RawAddress const& /*bd_addr*/, tBT_TRANSPORT /*transport*/) {
1758               return conn_id;
1759             });
1760     EXPECT_CALL(mock_btm_interface_, AclDisconnectFromHandle(conn_id, _)).Times(0);
1761     EXPECT_CALL(mock_gatt_interface_, Close(conn_id)).Times(1);
1762 
1763     do_in_main_thread(base::Bind(&LeAudioClient::Disconnect, base::Unretained(LeAudioClient::Get()),
1764                                  address));
1765     SyncOnMainLoop();
1766     Mock::VerifyAndClearExpectations(&mock_btm_interface_);
1767     Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
1768     Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
1769   }
1770 
DisconnectLeAudioWithAclClose(const RawAddress & address,uint16_t conn_id,tGATT_DISCONN_REASON reason=GATT_CONN_TERMINATE_LOCAL_HOST)1771   void DisconnectLeAudioWithAclClose(const RawAddress& address, uint16_t conn_id,
1772                                      tGATT_DISCONN_REASON reason = GATT_CONN_TERMINATE_LOCAL_HOST) {
1773     EXPECT_CALL(mock_audio_hal_client_callbacks_,
1774                 OnConnectionState(ConnectionState::DISCONNECTED, address))
1775             .Times(1);
1776 
1777     // For test purpose use the acl handle same as conn_id
1778     ON_CALL(mock_btm_interface_, GetHCIConnHandle(address, _))
1779             .WillByDefault([conn_id](RawAddress const& /*bd_addr*/, tBT_TRANSPORT /*transport*/) {
1780               return conn_id;
1781             });
1782     EXPECT_CALL(mock_btm_interface_, AclDisconnectFromHandle(conn_id, _))
1783             .WillOnce([this, &reason](uint16_t handle, tHCI_STATUS /*rs*/) {
1784               InjectDisconnectedEvent(handle, reason);
1785             });
1786     EXPECT_CALL(mock_gatt_interface_, Close(conn_id)).Times(0);
1787 
1788     do_in_main_thread(base::Bind(&LeAudioClient::Disconnect, base::Unretained(LeAudioClient::Get()),
1789                                  address));
1790     SyncOnMainLoop();
1791     Mock::VerifyAndClearExpectations(&mock_btm_interface_);
1792     Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
1793     Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
1794   }
1795 
DisconnectLeAudioNoDisconnectedEvtExpected(const RawAddress & address,uint16_t conn_id)1796   void DisconnectLeAudioNoDisconnectedEvtExpected(const RawAddress& address, uint16_t conn_id) {
1797     EXPECT_CALL(mock_gatt_interface_, Close(conn_id)).Times(0);
1798     EXPECT_CALL(mock_btm_interface_, AclDisconnectFromHandle(conn_id, _)).Times(1);
1799     do_in_main_thread(base::BindOnce(&LeAudioClient::Disconnect,
1800                                      base::Unretained(LeAudioClient::Get()), address));
1801     SyncOnMainLoop();
1802     Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
1803     Mock::VerifyAndClearExpectations(&mock_btm_interface_);
1804   }
1805 
ConnectCsisDevice(const RawAddress & addr,uint16_t conn_id,uint32_t sink_audio_allocation,uint32_t source_audio_allocation,uint8_t group_size,int group_id,uint8_t rank,bool connect_through_csis=false,bool new_device=true)1806   void ConnectCsisDevice(const RawAddress& addr, uint16_t conn_id, uint32_t sink_audio_allocation,
1807                          uint32_t source_audio_allocation, uint8_t group_size, int group_id,
1808                          uint8_t rank, bool connect_through_csis = false, bool new_device = true) {
1809     SetSampleDatabaseEarbudsValid(conn_id, addr, sink_audio_allocation, source_audio_allocation,
1810                                   default_channel_cnt, default_channel_cnt,
1811                                   0x0034, /* source sample freq 16/24k/32hz */
1812                                   true,   /*add_csis*/
1813                                   true,   /*add_cas*/
1814                                   true,   /*add_pacs*/
1815                                   true,   /*add_ascs*/
1816                                   group_size, rank);
1817     EXPECT_CALL(mock_audio_hal_client_callbacks_,
1818                 OnConnectionState(ConnectionState::CONNECTED, addr))
1819             .Times(1);
1820 
1821     if (new_device) {
1822       EXPECT_CALL(mock_audio_hal_client_callbacks_,
1823                   OnGroupNodeStatus(addr, group_id, GroupNodeStatus::ADDED))
1824               .Times(1);
1825     }
1826 
1827     if (connect_through_csis) {
1828       // Add it the way CSIS would do: add to group and then connect
1829       do_in_main_thread(base::BindOnce(&LeAudioClient::GroupAddNode,
1830                                        base::Unretained(LeAudioClient::Get()), group_id, addr));
1831       ConnectLeAudio(addr);
1832     } else {
1833       // The usual connect
1834       // Since device has CSIS, lets add it here to groups already now
1835       groups[addr] = group_id;
1836       ConnectLeAudio(addr);
1837       InjectGroupDeviceAdded(addr, group_id);
1838     }
1839   }
1840 
ConnectNonCsisDevice(const RawAddress & addr,uint16_t conn_id,uint32_t sink_audio_allocation,uint32_t source_audio_allocation)1841   void ConnectNonCsisDevice(const RawAddress& addr, uint16_t conn_id,
1842                             uint32_t sink_audio_allocation, uint32_t source_audio_allocation) {
1843     SetSampleDatabaseEarbudsValid(conn_id, addr, sink_audio_allocation, source_audio_allocation,
1844                                   default_channel_cnt, default_channel_cnt, 0x0004,
1845                                   /* source sample freq 16khz */ false, /*add_csis*/
1846                                   true,                                 /*add_cas*/
1847                                   true,                                 /*add_pacs*/
1848                                   true,                                 /*add_ascs*/
1849                                   0, 0);
1850     EXPECT_CALL(mock_audio_hal_client_callbacks_,
1851                 OnConnectionState(ConnectionState::CONNECTED, addr))
1852             .Times(1);
1853 
1854     ConnectLeAudio(addr);
1855   }
1856 
UpdateLocalSourceMetadata(std::vector<struct playback_track_metadata> tracks,bool reconfigure_existing_stream=false)1857   void UpdateLocalSourceMetadata(std::vector<struct playback_track_metadata> tracks,
1858                                  bool reconfigure_existing_stream = false) {
1859     std::vector<playback_track_metadata_v7> tracks_vec;
1860     tracks_vec.reserve(tracks.size());
1861     for (const auto& track : tracks) {
1862       playback_track_metadata_v7 desc_track = {
1863               .base =
1864                       {
1865                               .usage = static_cast<audio_usage_t>(track.usage),
1866                               .content_type = static_cast<audio_content_type_t>(track.content_type),
1867                               .gain = track.gain,
1868                       },
1869       };
1870       if (test_tags_ptr_) {
1871         memcpy(desc_track.tags, test_tags_ptr_, strlen(test_tags_ptr_));
1872       }
1873 
1874       tracks_vec.push_back(desc_track);
1875     }
1876 
1877     ASSERT_NE(nullptr, mock_le_audio_source_hal_client_);
1878     /* Local Source may reconfigure once the metadata is updated */
1879     if (reconfigure_existing_stream) {
1880       Expectation reconfigure =
1881               EXPECT_CALL(*mock_le_audio_source_hal_client_, SuspendedForReconfiguration())
1882                       .Times(1);
1883       EXPECT_CALL(*mock_le_audio_source_hal_client_, CancelStreamingRequest()).Times(1);
1884       EXPECT_CALL(*mock_le_audio_source_hal_client_, ReconfigurationComplete())
1885               .Times(1)
1886               .After(reconfigure);
1887     } else {
1888       EXPECT_CALL(*mock_le_audio_source_hal_client_, SuspendedForReconfiguration()).Times(0);
1889       EXPECT_CALL(*mock_le_audio_source_hal_client_, ReconfigurationComplete()).Times(0);
1890     }
1891 
1892     ASSERT_NE(unicast_source_hal_cb_, nullptr);
1893     unicast_source_hal_cb_->OnAudioMetadataUpdate(std::move(tracks_vec), DsaMode::DISABLED);
1894   }
1895 
UpdateLocalSourceMetadata(audio_usage_t usage,audio_content_type_t content_type,bool reconfigure_existing_stream=false)1896   void UpdateLocalSourceMetadata(audio_usage_t usage, audio_content_type_t content_type,
1897                                  bool reconfigure_existing_stream = false) {
1898     std::vector<struct playback_track_metadata> tracks = {
1899             {{AUDIO_USAGE_UNKNOWN, AUDIO_CONTENT_TYPE_UNKNOWN, 0},
1900              {AUDIO_USAGE_UNKNOWN, AUDIO_CONTENT_TYPE_UNKNOWN, 0}}};
1901 
1902     tracks[0].usage = usage;
1903     tracks[0].content_type = content_type;
1904     UpdateLocalSourceMetadata(tracks, reconfigure_existing_stream);
1905   }
1906 
UpdateLocalSinkMetadata(audio_source_t audio_source)1907   void UpdateLocalSinkMetadata(audio_source_t audio_source) {
1908     std::vector<struct record_track_metadata> tracks = {
1909             {{AUDIO_SOURCE_INVALID, 0.5, AUDIO_DEVICE_NONE, "00:11:22:33:44:55"},
1910              {AUDIO_SOURCE_MIC, 0.7, AUDIO_DEVICE_OUT_BLE_HEADSET, "AA:BB:CC:DD:EE:FF"}}};
1911 
1912     tracks[1].source = audio_source;
1913 
1914     std::vector<record_track_metadata_v7> tracks_vec;
1915     tracks_vec.reserve(tracks.size());
1916     for (const auto& track : tracks) {
1917       record_track_metadata_v7 desc_track = {
1918               .base =
1919                       {
1920                               .source = static_cast<audio_source_t>(track.source),
1921                               .gain = track.gain,
1922                               .dest_device = static_cast<audio_devices_t>(track.dest_device),
1923                       },
1924       };
1925 
1926       strcpy(desc_track.base.dest_device_address, track.dest_device_address);
1927       tracks_vec.push_back(desc_track);
1928     }
1929 
1930     ASSERT_NE(nullptr, unicast_sink_hal_cb_);
1931     unicast_sink_hal_cb_->OnAudioMetadataUpdate(std::move(tracks_vec));
1932   }
1933 
LocalAudioSourceSuspend(void)1934   void LocalAudioSourceSuspend(void) {
1935     ASSERT_NE(unicast_source_hal_cb_, nullptr);
1936     unicast_source_hal_cb_->OnAudioSuspend();
1937     SyncOnMainLoop();
1938   }
1939 
LocalAudioSourceResume(bool expected_confirmation=true,bool expected_cancel=false)1940   void LocalAudioSourceResume(bool expected_confirmation = true, bool expected_cancel = false) {
1941     ASSERT_NE(nullptr, mock_le_audio_source_hal_client_);
1942     if (expected_confirmation) {
1943       EXPECT_CALL(*mock_le_audio_source_hal_client_, ConfirmStreamingRequest()).Times(1);
1944     }
1945 
1946     if (expected_cancel) {
1947       EXPECT_CALL(*mock_le_audio_source_hal_client_, CancelStreamingRequest()).Times(1);
1948     }
1949 
1950     do_in_main_thread(base::BindOnce(
1951             [](LeAudioSourceAudioHalClient::Callbacks* cb) {
1952               if (cb) {
1953                 cb->OnAudioResume();
1954               }
1955             },
1956             unicast_source_hal_cb_));
1957 
1958     SyncOnMainLoop();
1959     Mock::VerifyAndClearExpectations(&*mock_le_audio_source_hal_client_);
1960   }
1961 
LocalAudioSinkSuspend(void)1962   void LocalAudioSinkSuspend(void) {
1963     ASSERT_NE(unicast_sink_hal_cb_, nullptr);
1964     unicast_sink_hal_cb_->OnAudioSuspend();
1965     SyncOnMainLoop();
1966   }
1967 
LocalAudioSinkResume(void)1968   void LocalAudioSinkResume(void) {
1969     ASSERT_NE(unicast_sink_hal_cb_, nullptr);
1970     do_in_main_thread(
1971             base::BindOnce([](LeAudioSinkAudioHalClient::Callbacks* cb) { cb->OnAudioResume(); },
1972                            unicast_sink_hal_cb_));
1973 
1974     SyncOnMainLoop();
1975     Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
1976   }
1977 
StartStreaming(audio_usage_t usage,audio_content_type_t content_type,int,audio_source_t audio_source=AUDIO_SOURCE_INVALID,bool reconfigure_existing_stream=false,bool expected_resume_confirmation=true)1978   void StartStreaming(audio_usage_t usage, audio_content_type_t content_type, int /*group_id*/,
1979                       audio_source_t audio_source = AUDIO_SOURCE_INVALID,
1980                       bool reconfigure_existing_stream = false,
1981                       bool expected_resume_confirmation = true) {
1982     ASSERT_NE(unicast_source_hal_cb_, nullptr);
1983 
1984     UpdateLocalSourceMetadata(usage, content_type, reconfigure_existing_stream);
1985     if (audio_source != AUDIO_SOURCE_INVALID) {
1986       UpdateLocalSinkMetadata(audio_source);
1987     }
1988 
1989     /* Stream has been automatically restarted on UpdateLocalSourceMetadata */
1990     if (reconfigure_existing_stream) {
1991       return;
1992     }
1993 
1994     LocalAudioSourceResume(expected_resume_confirmation);
1995     SyncOnMainLoop();
1996     Mock::VerifyAndClearExpectations(&mock_state_machine_);
1997 
1998     if (usage == AUDIO_USAGE_VOICE_COMMUNICATION || audio_source != AUDIO_SOURCE_INVALID) {
1999       ASSERT_NE(unicast_sink_hal_cb_, nullptr);
2000       do_in_main_thread(
2001               base::BindOnce([](LeAudioSinkAudioHalClient::Callbacks* cb) { cb->OnAudioResume(); },
2002                              unicast_sink_hal_cb_));
2003     }
2004     SyncOnMainLoop();
2005   }
2006 
StopStreaming(int,bool suspend_source=false)2007   void StopStreaming(int /*group_id*/, bool suspend_source = false) {
2008     ASSERT_NE(unicast_source_hal_cb_, nullptr);
2009 
2010     /* TODO We should have a way to confirm Stop() otherwise, audio framework
2011      * might have different state that it is in the le_audio code - as tearing
2012      * down CISes might take some time
2013      */
2014     /* It's enough to call only one resume even if it'll be bi-directional
2015      * streaming. First suspend will trigger GroupStop.
2016      *
2017      * There is no - 'only source receiver' scenario (e.g. single microphone).
2018      * If there will be such test oriented scenario, such resume choose logic
2019      * should be applied.
2020      */
2021     unicast_source_hal_cb_->OnAudioSuspend();
2022 
2023     if (suspend_source) {
2024       ASSERT_NE(unicast_sink_hal_cb_, nullptr);
2025       unicast_sink_hal_cb_->OnAudioSuspend();
2026     }
2027     SyncOnMainLoop();
2028   }
2029 
set_sample_database(uint16_t conn_id,RawAddress addr,std::unique_ptr<NiceMock<MockDeviceWrapper::csis_mock>> csis,std::unique_ptr<NiceMock<MockDeviceWrapper::cas_mock>> cas,std::unique_ptr<NiceMock<MockDeviceWrapper::ascs_mock>> ascs,std::unique_ptr<NiceMock<MockDeviceWrapper::pacs_mock>> pacs)2030   void set_sample_database(uint16_t conn_id, RawAddress addr,
2031                            std::unique_ptr<NiceMock<MockDeviceWrapper::csis_mock>> csis,
2032                            std::unique_ptr<NiceMock<MockDeviceWrapper::cas_mock>> cas,
2033                            std::unique_ptr<NiceMock<MockDeviceWrapper::ascs_mock>> ascs,
2034                            std::unique_ptr<NiceMock<MockDeviceWrapper::pacs_mock>> pacs) {
2035     gatt::DatabaseBuilder bob;
2036 
2037     /* Generic Access Service */
2038     bob.AddService(0x0001, 0x0003, Uuid::From16Bit(0x1800), true);
2039     /* Device Name Char. */
2040     bob.AddCharacteristic(0x0002, 0x0003, Uuid::From16Bit(0x2a00), GATT_CHAR_PROP_BIT_READ);
2041 
2042     if (csis->start) {
2043       bool is_primary = true;
2044       bob.AddService(csis->start, csis->end, bluetooth::csis::kCsisServiceUuid, is_primary);
2045       if (csis->sirk_char) {
2046         bob.AddCharacteristic(csis->sirk_char, csis->sirk_char + 1, bluetooth::csis::kCsisSirkUuid,
2047                               GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
2048         if (csis->sirk_ccc) {
2049           bob.AddDescriptor(csis->sirk_ccc, Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
2050         }
2051       }
2052 
2053       if (csis->size_char) {
2054         bob.AddCharacteristic(csis->size_char, csis->size_char + 1, bluetooth::csis::kCsisSizeUuid,
2055                               GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
2056         if (csis->size_ccc) {
2057           bob.AddDescriptor(csis->size_ccc, Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
2058         }
2059       }
2060 
2061       if (csis->lock_char) {
2062         bob.AddCharacteristic(
2063                 csis->lock_char, csis->lock_char + 1, bluetooth::csis::kCsisLockUuid,
2064                 GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY | GATT_CHAR_PROP_BIT_WRITE);
2065         if (csis->lock_ccc) {
2066           bob.AddDescriptor(csis->lock_ccc, Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
2067         }
2068       }
2069 
2070       if (csis->rank_char) {
2071         bob.AddCharacteristic(csis->rank_char, csis->rank_char + 1, bluetooth::csis::kCsisRankUuid,
2072                               GATT_CHAR_PROP_BIT_READ);
2073       }
2074     }
2075 
2076     if (cas->start) {
2077       bool is_primary = true;
2078       bob.AddService(cas->start, cas->end, bluetooth::le_audio::uuid::kCapServiceUuid, is_primary);
2079       // Include CSIS service inside
2080       if (cas->csis_include) {
2081         bob.AddIncludedService(cas->csis_include, bluetooth::csis::kCsisServiceUuid, csis->start,
2082                                csis->end);
2083       }
2084     }
2085 
2086     if (pacs->start) {
2087       bool is_primary = true;
2088       bob.AddService(pacs->start, pacs->end,
2089                      bluetooth::le_audio::uuid::kPublishedAudioCapabilityServiceUuid, is_primary);
2090 
2091       if (pacs->sink_pac_char) {
2092         bob.AddCharacteristic(
2093                 pacs->sink_pac_char, pacs->sink_pac_char + 1,
2094                 bluetooth::le_audio::uuid::kSinkPublishedAudioCapabilityCharacteristicUuid,
2095                 GATT_CHAR_PROP_BIT_READ);
2096         if (pacs->sink_pac_ccc) {
2097           bob.AddDescriptor(pacs->sink_pac_ccc, Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
2098         }
2099       }
2100 
2101       if (pacs->sink_audio_loc_char) {
2102         bob.AddCharacteristic(pacs->sink_audio_loc_char, pacs->sink_audio_loc_char + 1,
2103                               bluetooth::le_audio::uuid::kSinkAudioLocationCharacteristicUuid,
2104                               GATT_CHAR_PROP_BIT_READ);
2105         if (pacs->sink_audio_loc_ccc) {
2106           bob.AddDescriptor(pacs->sink_audio_loc_ccc,
2107                             Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
2108         }
2109       }
2110 
2111       if (pacs->source_pac_char) {
2112         bob.AddCharacteristic(
2113                 pacs->source_pac_char, pacs->source_pac_char + 1,
2114                 bluetooth::le_audio::uuid::kSourcePublishedAudioCapabilityCharacteristicUuid,
2115                 GATT_CHAR_PROP_BIT_READ);
2116         if (pacs->source_pac_ccc) {
2117           bob.AddDescriptor(pacs->source_pac_ccc, Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
2118         }
2119       }
2120 
2121       if (pacs->source_audio_loc_char) {
2122         bob.AddCharacteristic(pacs->source_audio_loc_char, pacs->source_audio_loc_char + 1,
2123                               bluetooth::le_audio::uuid::kSourceAudioLocationCharacteristicUuid,
2124                               GATT_CHAR_PROP_BIT_READ);
2125         if (pacs->source_audio_loc_ccc) {
2126           bob.AddDescriptor(pacs->source_audio_loc_ccc,
2127                             Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
2128         }
2129       }
2130 
2131       if (pacs->avail_contexts_char) {
2132         bob.AddCharacteristic(
2133                 pacs->avail_contexts_char, pacs->avail_contexts_char + 1,
2134                 bluetooth::le_audio::uuid::kAudioContextAvailabilityCharacteristicUuid,
2135                 GATT_CHAR_PROP_BIT_READ);
2136         if (pacs->avail_contexts_ccc) {
2137           bob.AddDescriptor(pacs->avail_contexts_ccc,
2138                             Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
2139         }
2140       }
2141 
2142       if (pacs->supp_contexts_char) {
2143         bob.AddCharacteristic(pacs->supp_contexts_char, pacs->supp_contexts_char + 1,
2144                               bluetooth::le_audio::uuid::kAudioSupportedContextCharacteristicUuid,
2145                               GATT_CHAR_PROP_BIT_READ);
2146         if (pacs->supp_contexts_ccc) {
2147           bob.AddDescriptor(pacs->supp_contexts_ccc, Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
2148         }
2149       }
2150     }
2151 
2152     if (ascs->start) {
2153       bool is_primary = true;
2154       bob.AddService(ascs->start, ascs->end,
2155                      bluetooth::le_audio::uuid::kAudioStreamControlServiceUuid, is_primary);
2156       for (int i = 0; i < max_num_of_ases; i++) {
2157         if (ascs->sink_ase_char[i]) {
2158           bob.AddCharacteristic(ascs->sink_ase_char[i], ascs->sink_ase_char[i] + 1,
2159                                 bluetooth::le_audio::uuid::kSinkAudioStreamEndpointUuid,
2160                                 GATT_CHAR_PROP_BIT_READ);
2161           if (ascs->sink_ase_ccc[i]) {
2162             bob.AddDescriptor(ascs->sink_ase_ccc[i], Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
2163           }
2164         }
2165         if (ascs->source_ase_char[i]) {
2166           bob.AddCharacteristic(ascs->source_ase_char[i], ascs->source_ase_char[i] + 1,
2167                                 bluetooth::le_audio::uuid::kSourceAudioStreamEndpointUuid,
2168                                 GATT_CHAR_PROP_BIT_READ);
2169           if (ascs->source_ase_ccc[i]) {
2170             bob.AddDescriptor(ascs->source_ase_ccc[i],
2171                               Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
2172           }
2173         }
2174       }
2175       if (ascs->ctp_char) {
2176         bob.AddCharacteristic(
2177                 ascs->ctp_char, ascs->ctp_char + 1,
2178                 bluetooth::le_audio::uuid::kAudioStreamEndpointControlPointCharacteristicUuid,
2179                 GATT_CHAR_PROP_BIT_READ);
2180         if (ascs->ctp_ccc) {
2181           bob.AddDescriptor(ascs->ctp_ccc, Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
2182         }
2183       }
2184     }
2185 
2186     // Assign conn_id to a certain device - this does not mean it is connected
2187     auto dev_wrapper = std::make_unique<NiceMock<MockDeviceWrapper>>(
2188             addr, bob.Build().Services(), std::move(csis), std::move(cas), std::move(ascs),
2189             std::move(pacs));
2190     peer_devices.emplace(conn_id, std::move(dev_wrapper));
2191   }
2192 
SetSampleDatabaseEmpty(uint16_t conn_id,RawAddress addr)2193   void SetSampleDatabaseEmpty(uint16_t conn_id, RawAddress addr) {
2194     auto csis = std::make_unique<NiceMock<MockDeviceWrapper::csis_mock>>();
2195     auto cas = std::make_unique<NiceMock<MockDeviceWrapper::cas_mock>>();
2196     auto pacs = std::make_unique<NiceMock<MockDeviceWrapper::pacs_mock>>();
2197     auto ascs = std::make_unique<NiceMock<MockDeviceWrapper::ascs_mock>>();
2198     set_sample_database(conn_id, addr, std::move(csis), std::move(cas), std::move(ascs),
2199                         std::move(pacs));
2200   }
2201 
2202   struct SampleDatabaseParameters {
2203     uint16_t conn_id;
2204     RawAddress addr;
2205 
2206     uint32_t sink_audio_allocation = codec_spec_conf::kLeAudioLocationStereo;
2207     uint32_t source_audio_allocation = codec_spec_conf::kLeAudioLocationStereo;
2208     uint8_t sink_channel_cnt = 0x03;
2209     uint8_t source_channel_cnt = 0x03;
2210     uint16_t sample_freq_mask = 0x0004;
2211     bool add_csis = true;
2212     bool add_cas = true;
2213     bool add_pacs = true;
2214     int add_ascs_cnt = 1;
2215     uint8_t set_size = 2;
2216     uint8_t rank = 1;
2217     GattStatus gatt_status = GATT_SUCCESS;
2218     uint8_t max_supported_codec_frames_per_sdu = 1;
2219   };
2220 
SetSampleDatabaseEarbudsValid(uint16_t conn_id,RawAddress addr,uint32_t sink_audio_allocation,uint32_t source_audio_allocation,uint8_t sink_channel_cnt=0x03,uint8_t source_channel_cnt=0x03,uint16_t sample_freq_mask=0x0004,bool add_csis=true,bool add_cas=true,bool add_pacs=true,int add_ascs_cnt=1,uint8_t set_size=2,uint8_t rank=1,GattStatus gatt_status=GATT_SUCCESS)2221   void SetSampleDatabaseEarbudsValid(
2222           uint16_t conn_id, RawAddress addr, uint32_t sink_audio_allocation,
2223           uint32_t source_audio_allocation, uint8_t sink_channel_cnt = 0x03,
2224           uint8_t source_channel_cnt = 0x03, uint16_t sample_freq_mask = 0x0004,
2225           bool add_csis = true, bool add_cas = true, bool add_pacs = true, int add_ascs_cnt = 1,
2226           uint8_t set_size = 2, uint8_t rank = 1, GattStatus gatt_status = GATT_SUCCESS) {
2227     SetSampleDatabaseEarbudsValid(SampleDatabaseParameters{
2228             .conn_id = conn_id,
2229             .addr = addr,
2230             .sink_audio_allocation = sink_audio_allocation,
2231             .source_audio_allocation = source_audio_allocation,
2232             .sink_channel_cnt = sink_channel_cnt,
2233             .source_channel_cnt = source_channel_cnt,
2234             .sample_freq_mask = sample_freq_mask,
2235             .add_csis = add_csis,
2236             .add_cas = add_cas,
2237             .add_pacs = add_pacs,
2238             .add_ascs_cnt = add_ascs_cnt,
2239             .set_size = set_size,
2240             .rank = rank,
2241             .gatt_status = gatt_status,
2242             .max_supported_codec_frames_per_sdu = 1,
2243     });
2244   }
2245 
SetSampleDatabaseEarbudsValid(const SampleDatabaseParameters & params)2246   void SetSampleDatabaseEarbudsValid(const SampleDatabaseParameters& params) {
2247     auto conn_id = params.conn_id;
2248     auto addr = params.addr;
2249     auto sink_audio_allocation = params.sink_audio_allocation;
2250     auto source_audio_allocation = params.source_audio_allocation;
2251     auto sink_channel_cnt = params.sink_channel_cnt;
2252     auto source_channel_cnt = params.source_channel_cnt;
2253     auto sample_freq_mask = params.sample_freq_mask;
2254     auto add_csis = params.add_csis;
2255     auto add_cas = params.add_cas;
2256     auto add_pacs = params.add_pacs;
2257     auto add_ascs_cnt = params.add_ascs_cnt;
2258     auto set_size = params.set_size;
2259     auto rank = params.rank;
2260     auto gatt_status = params.gatt_status;
2261     auto max_supported_codec_frames_per_sdu = params.max_supported_codec_frames_per_sdu;
2262 
2263     auto csis = std::make_unique<NiceMock<MockDeviceWrapper::csis_mock>>();
2264     if (add_csis) {
2265       // attribute handles
2266       csis->start = 0x0010;
2267       csis->sirk_char = 0x0020;
2268       csis->sirk_ccc = 0x0022;
2269       csis->size_char = 0x0023;
2270       csis->size_ccc = 0x0025;
2271       csis->lock_char = 0x0026;
2272       csis->lock_ccc = 0x0028;
2273       csis->rank_char = 0x0029;
2274       csis->end = 0x0030;
2275       // other params
2276       csis->size = set_size;
2277       csis->rank = rank;
2278     }
2279 
2280     auto cas = std::make_unique<NiceMock<MockDeviceWrapper::cas_mock>>();
2281     if (add_cas) {
2282       // attribute handles
2283       cas->start = 0x0040;
2284       if (add_csis) {
2285         cas->csis_include = 0x0041;
2286       }
2287       cas->end = 0x0050;
2288       // other params
2289     }
2290 
2291     auto pacs = std::make_unique<NiceMock<MockDeviceWrapper::pacs_mock>>();
2292     if (add_pacs) {
2293       // attribute handles
2294       pacs->start = 0x0060;
2295       pacs->sink_pac_char = 0x0061;
2296       pacs->sink_pac_ccc = 0x0063;
2297       pacs->sink_audio_loc_char = 0x0064;
2298       pacs->sink_audio_loc_ccc = 0x0066;
2299       pacs->source_pac_char = 0x0067;
2300       pacs->source_pac_ccc = 0x0069;
2301       pacs->source_audio_loc_char = 0x0070;
2302       pacs->source_audio_loc_ccc = 0x0072;
2303       pacs->avail_contexts_char = 0x0073;
2304       pacs->avail_contexts_ccc = 0x0075;
2305       pacs->supp_contexts_char = 0x0076;
2306       pacs->supp_contexts_ccc = 0x0078;
2307       pacs->end = 0x0080;
2308       // other params
2309     }
2310 
2311     auto ascs = std::make_unique<NiceMock<MockDeviceWrapper::ascs_mock>>();
2312     if (add_ascs_cnt > 0) {
2313       // attribute handles
2314       ascs->start = 0x0090;
2315       uint16_t handle = 0x0091;
2316       for (int i = 0; i < add_ascs_cnt; i++) {
2317         if (sink_audio_allocation != 0) {
2318           ascs->sink_ase_char[i] = handle;
2319           handle += 2;
2320           ascs->sink_ase_ccc[i] = handle;
2321           handle++;
2322         }
2323 
2324         if (source_audio_allocation != 0) {
2325           ascs->source_ase_char[i] = handle;
2326           handle += 2;
2327           ascs->source_ase_ccc[i] = handle;
2328           handle++;
2329         }
2330       }
2331       ascs->ctp_char = handle;
2332       handle += 2;
2333       ascs->ctp_ccc = handle;
2334       handle++;
2335       ascs->end = handle;
2336       // other params
2337     }
2338 
2339     set_sample_database(conn_id, addr, std::move(csis), std::move(cas), std::move(ascs),
2340                         std::move(pacs));
2341 
2342     if (add_pacs) {
2343       uint8_t snk_allocation[4];
2344       uint8_t src_allocation[4];
2345 
2346       snk_allocation[0] = (uint8_t)(sink_audio_allocation);
2347       snk_allocation[1] = (uint8_t)(sink_audio_allocation >> 8);
2348       snk_allocation[2] = (uint8_t)(sink_audio_allocation >> 16);
2349       snk_allocation[3] = (uint8_t)(sink_audio_allocation >> 24);
2350 
2351       src_allocation[0] = (uint8_t)(source_audio_allocation);
2352       src_allocation[1] = (uint8_t)(source_audio_allocation >> 8);
2353       src_allocation[2] = (uint8_t)(source_audio_allocation >> 16);
2354       src_allocation[3] = (uint8_t)(source_audio_allocation >> 24);
2355 
2356       uint8_t sample_freq[2];
2357       sample_freq[0] = (uint8_t)(sample_freq_mask);
2358       sample_freq[1] = (uint8_t)(sample_freq_mask >> 8);
2359 
2360       // Set pacs default read values
2361       ON_CALL(*peer_devices.at(conn_id)->pacs, OnGetCharacteristicValue(_))
2362               .WillByDefault([=, this](uint16_t handle) {
2363                 auto& pacs = peer_devices.at(conn_id)->pacs;
2364                 std::vector<uint8_t> value;
2365                 if (gatt_status == GATT_SUCCESS) {
2366                   if (handle == pacs->sink_pac_char + 1) {
2367                     if (empty_sink_pack_) {
2368                       value = {0x00};
2369                     } else {
2370                       value = {
2371                               // Num records
2372                               0x02,
2373                               // Codec_ID
2374                               0x06,
2375                               0x00,
2376                               0x00,
2377                               0x00,
2378                               0x00,
2379                               // Codec Spec. Caps. Len
2380                               0x10,
2381                               0x03, /* sample freq */
2382                               0x01,
2383                               sample_freq[0],
2384                               sample_freq[1],
2385                               0x02,
2386                               0x02, /* frame duration */
2387                               0x03,
2388                               0x02, /* channel count */
2389                               0x03,
2390                               sink_channel_cnt,
2391                               0x05,
2392                               0x04,
2393                               0x1E,
2394                               0x00,
2395                               0x78,
2396                               0x00,
2397                               // Metadata Length
2398                               0x00,
2399                               // Codec_ID
2400                               0x06,
2401                               0x00,
2402                               0x00,
2403                               0x00,
2404                               0x00,
2405                               // Codec Spec. Caps. Len
2406                               0x13,
2407                               0x03, /* sample freq */
2408                               0x01,
2409                               0x80, /* 48kHz */
2410                               0x00,
2411                               0x02, /* frame duration */
2412                               0x02,
2413                               0x03,
2414                               0x02, /* channel count */
2415                               0x03,
2416                               sink_channel_cnt,
2417                               0x05, /* octects per frame */
2418                               0x04,
2419                               0x78,
2420                               0x00,
2421                               0x78,
2422                               0x00,
2423                               0x02, /* Max supported codec frames per SDU */
2424                               0x05,
2425                               max_supported_codec_frames_per_sdu,
2426                               // Metadata Length
2427                               0x00,
2428                       };
2429                     }
2430                   } else if (handle == pacs->sink_audio_loc_char + 1) {
2431                     value = {
2432                             // Audio Locations
2433                             snk_allocation[0],
2434                             snk_allocation[1],
2435                             snk_allocation[2],
2436                             snk_allocation[3],
2437                     };
2438                   } else if (handle == pacs->source_pac_char + 1) {
2439                     if (empty_source_pack_) {
2440                       value = {0x00};
2441                     } else {
2442                       value = {
2443                               // Num records
2444                               0x02,
2445                               // Codec_ID
2446                               0x06,
2447                               0x00,
2448                               0x00,
2449                               0x00,
2450                               0x00,
2451                               // Codec Spec. Caps. Len
2452                               0x10,
2453                               0x03,
2454                               0x01,
2455                               sample_freq[0],
2456                               sample_freq[1],
2457                               0x02,
2458                               0x02,
2459                               0x03,
2460                               0x02,
2461                               0x03,
2462                               source_channel_cnt,
2463                               0x05,
2464                               0x04,
2465                               0x1E,
2466                               0x00,
2467                               0x78,
2468                               0x00,
2469                               // Metadata Length
2470                               0x00,
2471                               // Codec_ID
2472                               0x06,
2473                               0x00,
2474                               0x00,
2475                               0x00,
2476                               0x00,
2477                               // Codec Spec. Caps. Len
2478                               0x10,
2479                               0x03,
2480                               0x01,
2481                               0x24,
2482                               0x00,
2483                               0x02,
2484                               0x02,
2485                               0x03,
2486                               0x02,
2487                               0x03,
2488                               source_channel_cnt,
2489                               0x05,
2490                               0x04,
2491                               0x1E,
2492                               0x00,
2493                               0x50,
2494                               0x00,
2495                               // Metadata Length
2496                               0x00,
2497                       };
2498                     }
2499                   } else if (handle == pacs->source_audio_loc_char + 1) {
2500                     value = {
2501                             // Audio Locations
2502                             src_allocation[0],
2503                             src_allocation[1],
2504                             src_allocation[2],
2505                             src_allocation[3],
2506                     };
2507                   } else if (handle == pacs->avail_contexts_char + 1) {
2508                     value = {
2509                             // Sink Avail Contexts
2510                             (uint8_t)(available_snk_context_types_),
2511                             (uint8_t)(available_snk_context_types_ >> 8),
2512                             // Source Avail Contexts
2513                             (uint8_t)(available_src_context_types_),
2514                             (uint8_t)(available_src_context_types_ >> 8),
2515                     };
2516                   } else if (handle == pacs->supp_contexts_char + 1) {
2517                     value = {
2518                             // Sink Supp Contexts
2519                             (uint8_t)(supported_snk_context_types_),
2520                             (uint8_t)(supported_snk_context_types_ >> 8),
2521                             // Source Supp Contexts
2522                             (uint8_t)(supported_src_context_types_),
2523                             (uint8_t)(supported_src_context_types_ >> 8),
2524                     };
2525                   }
2526                 }
2527                 return std::make_pair(gatt_status, value);
2528               });
2529     }
2530 
2531     if (add_ascs_cnt > 0) {
2532       // Set ascs default read values
2533       ON_CALL(*peer_devices.at(conn_id)->ascs, OnGetCharacteristicValue(_))
2534               .WillByDefault([this, conn_id, gatt_status](uint16_t handle) {
2535                 auto& ascs = peer_devices.at(conn_id)->ascs;
2536                 std::vector<uint8_t> value;
2537                 bool is_ase_sink_request = false;
2538                 bool is_ase_src_request = false;
2539                 uint8_t idx;
2540 
2541                 if (handle == ascs->ctp_ccc && ccc_stored_byte_val_.has_value()) {
2542                   value = {*ccc_stored_byte_val_, 00};
2543                   return std::make_pair(gatt_read_ctp_ccc_status_, value);
2544                 }
2545 
2546                 if (gatt_status == GATT_SUCCESS) {
2547                   if (handle == ascs->ctp_ccc) {
2548                     value = UINT16_TO_VEC_UINT8(ascs->ctp_ccc_val);
2549                   } else {
2550                     for (idx = 0; idx < max_num_of_ases; idx++) {
2551                       if (handle == ascs->sink_ase_ccc[idx] + 1) {
2552                         value = UINT16_TO_VEC_UINT8(ascs->sink_ase_ccc_val[idx]);
2553                         break;
2554                       }
2555                       if (handle == ascs->source_ase_char[idx] + 1) {
2556                         value = UINT16_TO_VEC_UINT8(ascs->source_ase_ccc_val[idx]);
2557                         break;
2558                       }
2559                     }
2560                   }
2561 
2562                   for (idx = 0; idx < max_num_of_ases; idx++) {
2563                     if (handle == ascs->sink_ase_char[idx] + 1) {
2564                       is_ase_sink_request = true;
2565                       break;
2566                     }
2567                     if (handle == ascs->source_ase_char[idx] + 1) {
2568                       is_ase_src_request = true;
2569                       break;
2570                     }
2571                   }
2572 
2573                   if (is_ase_sink_request) {
2574                     value = {
2575                             // ASE ID
2576                             static_cast<uint8_t>(idx + 1),
2577                             // State
2578                             static_cast<uint8_t>(bluetooth::le_audio::types::AseState::
2579                                                          BTA_LE_AUDIO_ASE_STATE_IDLE),
2580                             // No Additional ASE params for IDLE state
2581                     };
2582                   } else if (is_ase_src_request) {
2583                     value = {
2584                             // ASE ID
2585                             static_cast<uint8_t>(idx + 6),
2586                             // State
2587                             static_cast<uint8_t>(bluetooth::le_audio::types::AseState::
2588                                                          BTA_LE_AUDIO_ASE_STATE_IDLE),
2589                             // No Additional ASE params for IDLE state
2590                     };
2591                   }
2592                 }
2593                 return std::make_pair(gatt_status, value);
2594               });
2595     }
2596   }
2597 
TestAudioDataTransfer(int group_id,uint8_t cis_count_out,uint8_t cis_count_in,int data_len,int in_data_len=40,uint16_t decoded_in_data_len=0)2598   void TestAudioDataTransfer(int group_id, uint8_t cis_count_out, uint8_t cis_count_in,
2599                              int data_len, int in_data_len = 40, uint16_t decoded_in_data_len = 0) {
2600     ASSERT_NE(unicast_source_hal_cb_, nullptr);
2601     ASSERT_NE(mock_le_audio_sink_hal_client_, nullptr);
2602 
2603     // Expect two channels ISO Data to be sent
2604     std::vector<uint16_t> handles;
2605     if (cis_count_out) {
2606       EXPECT_CALL(*mock_iso_manager_, SendIsoData(_, _, _))
2607               .Times(cis_count_out)
2608               .WillRepeatedly([&handles](uint16_t iso_handle, const uint8_t* /*data*/,
2609                                          uint16_t /*data_len*/) { handles.push_back(iso_handle); });
2610     }
2611     std::vector<uint8_t> data(data_len);
2612     unicast_source_hal_cb_->OnAudioDataReady(data);
2613 
2614     // Inject microphone data from group (2 CISes - pass stereo data in 1 call)
2615     if (decoded_in_data_len) {
2616       EXPECT_CALL(*mock_le_audio_sink_hal_client_, SendData(_, decoded_in_data_len))
2617               .Times(cis_count_in > 0 ? 1 : 0);
2618     } else {
2619       EXPECT_CALL(*mock_le_audio_sink_hal_client_, SendData(_, _)).Times(cis_count_in > 0 ? 1 : 0);
2620     }
2621     ASSERT_EQ(streaming_groups.count(group_id), 1u);
2622 
2623     if (cis_count_in) {
2624       ASSERT_NE(unicast_sink_hal_cb_, nullptr);
2625 
2626       ASSERT_NE(0lu, streaming_groups.count(group_id));
2627       auto group = streaming_groups.at(group_id);
2628       for (LeAudioDevice* device = group->GetFirstDevice(); device != nullptr;
2629            device = group->GetNextDevice(device)) {
2630         for (auto& ase : device->ases_) {
2631           if (ase.direction == bluetooth::le_audio::types::kLeAudioDirectionSource) {
2632             InjectIncomingIsoData(group_id, ase.cis_conn_hdl, in_data_len);
2633             --cis_count_in;
2634             if (!cis_count_in) {
2635               break;
2636             }
2637           }
2638         }
2639         if (!cis_count_in) {
2640           break;
2641         }
2642       }
2643     }
2644 
2645     SyncOnMainLoop();
2646     std::sort(handles.begin(), handles.end());
2647     ASSERT_EQ(cis_count_in, 0);
2648     handles.clear();
2649 
2650     Mock::VerifyAndClearExpectations(mock_iso_manager_);
2651     Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
2652   }
2653 
InjectIncomingIsoData(uint16_t cig_id,uint16_t cis_con_hdl,size_t payload_size)2654   void InjectIncomingIsoData(uint16_t cig_id, uint16_t cis_con_hdl, size_t payload_size) {
2655     BT_HDR* bt_hdr = (BT_HDR*)malloc(sizeof(BT_HDR) + payload_size);
2656 
2657     bt_hdr->offset = 0;
2658     bt_hdr->len = payload_size;
2659 
2660     bluetooth::hci::iso_manager::cis_data_evt cis_evt;
2661     cis_evt.cig_id = cig_id;
2662     cis_evt.cis_conn_hdl = cis_con_hdl;
2663     cis_evt.ts = 0;
2664     cis_evt.evt_lost = 0;
2665     cis_evt.p_msg = bt_hdr;
2666 
2667     ASSERT_NE(cig_callbacks_, nullptr);
2668     cig_callbacks_->OnCisEvent(bluetooth::hci::iso_manager::kIsoEventCisDataAvailable, &cis_evt);
2669     free(bt_hdr);
2670   }
2671 
InjectCisDisconnected(uint16_t cig_id,uint16_t cis_con_hdl,uint8_t reason=0)2672   void InjectCisDisconnected(uint16_t cig_id, uint16_t cis_con_hdl, uint8_t reason = 0) {
2673     bluetooth::hci::iso_manager::cis_disconnected_evt cis_evt;
2674     cis_evt.cig_id = cig_id;
2675     cis_evt.cis_conn_hdl = cis_con_hdl;
2676     cis_evt.reason = reason;
2677 
2678     ASSERT_NE(cig_callbacks_, nullptr);
2679     cig_callbacks_->OnCisEvent(bluetooth::hci::iso_manager::kIsoEventCisDisconnected, &cis_evt);
2680   }
2681 
InjectCigRemoved(uint8_t cig_id)2682   void InjectCigRemoved(uint8_t cig_id) {
2683     bluetooth::hci::iso_manager::cig_remove_cmpl_evt evt;
2684     evt.status = 0;
2685     evt.cig_id = cig_id;
2686 
2687     ASSERT_NE(cig_callbacks_, nullptr);
2688     cig_callbacks_->OnCisEvent(bluetooth::hci::iso_manager::kIsoEventCigOnRemoveCmpl, &evt);
2689   }
2690 
2691   NiceMock<MockAudioHalClientCallbacks> mock_audio_hal_client_callbacks_;
2692   LeAudioSourceAudioHalClient::Callbacks* unicast_source_hal_cb_ = nullptr;
2693   LeAudioSinkAudioHalClient::Callbacks* unicast_sink_hal_cb_ = nullptr;
2694 
2695   uint8_t default_channel_cnt = 0x03;
2696   uint8_t default_ase_cnt = 1;
2697 
2698   NiceMock<MockCsisClient> mock_csis_client_module_;
2699   NiceMock<MockDeviceGroups> mock_groups_module_;
2700   bluetooth::groups::DeviceGroupsCallbacks* group_callbacks_;
2701   NiceMock<MockLeAudioGroupStateMachine> mock_state_machine_;
2702 
2703   NiceMock<MockFunction<void()>> mock_storage_load;
2704   NiceMock<MockFunction<bool()>> mock_hal_2_1_verifier;
2705 
2706   NiceMock<bluetooth::manager::MockBtmInterface> mock_btm_interface_;
2707   NiceMock<gatt::MockBtaGattInterface> mock_gatt_interface_;
2708   NiceMock<gatt::MockBtaGattQueue> mock_gatt_queue_;
2709   tBTA_GATTC_CBACK* gatt_callback;
2710   const uint8_t gatt_if = 0xfe;
2711   uint16_t global_conn_id = 1;
2712   bluetooth::le_audio::LeAudioGroupStateMachine::Callbacks* state_machine_callbacks_;
2713   std::map<int, LeAudioDeviceGroup*> streaming_groups;
2714   bool stay_at_qos_config_in_start_stream = false;
2715   bool stay_at_releasing_stop_stream = false;
2716 
2717   bool attach_to_stream_scheduled = false;
2718 
2719   bluetooth::hci::IsoManager* iso_manager_;
2720   MockIsoManager* mock_iso_manager_;
2721   bluetooth::hci::iso_manager::CigCallbacks* cig_callbacks_ = nullptr;
2722   uint16_t iso_con_counter_ = 1;
2723 
2724   bluetooth::le_audio::CodecManager* codec_manager_;
2725   MockCodecManager* mock_codec_manager_;
2726 
2727   uint16_t available_snk_context_types_ = 0xffff;
2728   uint16_t available_src_context_types_ = 0xffff;
2729   uint16_t supported_snk_context_types_ = 0xffff;
2730   uint16_t supported_src_context_types_ = 0xffff;
2731 
2732   bool empty_source_pack_;
2733   bool empty_sink_pack_;
2734 
2735   NiceMock<bluetooth::storage::MockBtifStorageInterface> mock_btif_storage_;
2736 
2737   std::map<uint16_t, std::unique_ptr<NiceMock<MockDeviceWrapper>>> peer_devices;
2738   std::list<int> group_locks;
2739   std::map<RawAddress, int> groups;
2740 
2741   /* CCC descriptor data */
2742   tGATT_STATUS gatt_read_ctp_ccc_status_ = GATT_SUCCESS;
2743   std::optional<uint8_t> ccc_stored_byte_val_ = std::nullopt;
2744 
2745   /* Audio track metadata */
2746   char* test_tags_ptr_ = nullptr;
2747   NiceMock<bluetooth::hci::testing::MockControllerInterface> controller_;
2748 };
2749 
2750 class UnicastTest : public UnicastTestNoInit {
2751 protected:
SetUp()2752   void SetUp() override {
2753     UnicastTestNoInit::SetUp();
2754 
2755     EXPECT_CALL(mock_hal_2_1_verifier, Call()).Times(1);
2756     EXPECT_CALL(mock_storage_load, Call()).Times(1);
2757 
2758     ON_CALL(mock_btm_interface_, GetHCIConnHandle(_, _))
2759             .WillByDefault(
2760                     [this](RawAddress const& bd_addr, tBT_TRANSPORT /*transport*/) -> uint16_t {
2761                       for (auto const& [conn_id, dev_wrapper] : peer_devices) {
2762                         if (dev_wrapper->addr == bd_addr) {
2763                           return conn_id;
2764                         }
2765                       }
2766                       log::error("GetHCIConnHandle Mock: not a valid test device!");
2767                       return 0x00FE;
2768                     });
2769     ON_CALL(mock_btm_interface_, AclDisconnectFromHandle(_, _))
2770             .WillByDefault([this](uint16_t handle, tHCI_STATUS /*rs*/) {
2771               ASSERT_NE(handle, GATT_INVALID_CONN_ID);
2772               InjectDisconnectedEvent(handle, GATT_CONN_TERMINATE_LOCAL_HOST);
2773             });
2774 
2775     std::vector<::bluetooth::le_audio::btle_audio_codec_config_t> framework_encode_preference;
2776     BtaAppRegisterCallback app_register_callback;
2777     EXPECT_CALL(mock_gatt_interface_, AppRegister(_, _, _))
2778             .WillOnce(DoAll(SaveArg<0>(&gatt_callback), SaveArg<1>(&app_register_callback)));
2779     LeAudioClient::Initialize(
2780             &mock_audio_hal_client_callbacks_,
2781             base::Bind([](MockFunction<void()>* foo) { foo->Call(); }, &mock_storage_load),
2782             base::Bind([](MockFunction<bool()>* foo) { return foo->Call(); },
2783                        &mock_hal_2_1_verifier),
2784             framework_encode_preference);
2785 
2786     SyncOnMainLoop();
2787     ASSERT_TRUE(gatt_callback);
2788     ASSERT_TRUE(group_callbacks_);
2789     ASSERT_TRUE(app_register_callback);
2790     app_register_callback.Run(gatt_if, GATT_SUCCESS);
2791     Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
2792   }
2793 
TearDown()2794   void TearDown() override {
2795     MockCodecInterface::ClearMockInstanceHookList();
2796 
2797     // Clear the default actions before the parent class teardown is called
2798     Mock::VerifyAndClear(&mock_btm_interface_);
2799     Mock::VerifyAndClear(&mock_gatt_interface_);
2800     Mock::VerifyAndClear(&mock_audio_hal_client_callbacks_);
2801     groups.clear();
2802     UnicastTestNoInit::TearDown();
2803   }
2804 
TestSetupRemoteDevices(int group_id)2805   void TestSetupRemoteDevices(int group_id) {
2806     uint8_t group_size = 2;
2807 
2808     // Report working CSIS
2809     ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
2810 
2811     // First earbud
2812     const RawAddress test_address0 = GetTestAddress(0);
2813     EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
2814     ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
2815                       codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id,
2816                       1 /* rank*/);
2817 
2818     // Second earbud
2819     const RawAddress test_address1 = GetTestAddress(1);
2820     EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
2821     ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
2822                       codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id,
2823                       2 /* rank*/, true /*connect_through_csis*/);
2824 
2825     constexpr int gmcs_ccid = 1;
2826     constexpr int gtbs_ccid = 2;
2827     EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
2828     EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
2829     LeAudioClient::Get()->SetCcidInformation(gmcs_ccid,
2830                                              static_cast<int>(LeAudioContextType::MEDIA));
2831     LeAudioClient::Get()->SetCcidInformation(gtbs_ccid,
2832                                              static_cast<int>(LeAudioContextType::CONVERSATIONAL));
2833     LeAudioClient::Get()->GroupSetActive(group_id);
2834   }
2835 
TestSetCodecPreference(const btle_audio_codec_config_t * preferred_codec_config_before_streaming,const btle_audio_codec_config_t * preferred_codec_config_during_streaming,LeAudioContextType context_type,int group_id,bool set_before_streaming,bool set_while_streaming,bool is_using_set_before_streaming_codec_during_streaming,bool is_using_set_while_streaming_codec_during_streaming,bool is_reconfig)2836   void TestSetCodecPreference(
2837           const btle_audio_codec_config_t* preferred_codec_config_before_streaming,
2838           const btle_audio_codec_config_t* preferred_codec_config_during_streaming,
2839           LeAudioContextType context_type, int group_id, bool set_before_streaming,
2840           bool set_while_streaming, bool is_using_set_before_streaming_codec_during_streaming,
2841           bool is_using_set_while_streaming_codec_during_streaming, bool is_reconfig) {
2842     auto config_before_streaming_str = preferred_codec_config_before_streaming
2843                                                ? preferred_codec_config_before_streaming->ToString()
2844                                                : "null";
2845     auto config_during_streaming_str = preferred_codec_config_during_streaming
2846                                                ? preferred_codec_config_during_streaming->ToString()
2847                                                : "null";
2848     log::debug(
2849             "preferred_codec_config_before_streaming: {}, "
2850             "preferred_codec_config_during_streaming: {}, context_type: {}, "
2851             "group_id: {}, set_before_streaming: {}, "
2852             "set_while_streaming: {}, "
2853             "is_using_set_before_streaming_codec_during_streaming: "
2854             "{},is_using_set_while_streaming_codec_during_streaming:{}, "
2855             "is_reconfig: {}",
2856             config_before_streaming_str, config_during_streaming_str,
2857             bluetooth::common::ToString(context_type), group_id, set_before_streaming,
2858             set_while_streaming, is_using_set_before_streaming_codec_during_streaming,
2859             is_using_set_while_streaming_codec_during_streaming, is_reconfig);
2860 
2861     if (context_type != LeAudioContextType::MEDIA &&
2862         context_type != LeAudioContextType::CONVERSATIONAL) {
2863       return;
2864     }
2865 
2866     if (set_before_streaming) {
2867       do_in_main_thread(base::BindOnce(&LeAudioClient::SetCodecConfigPreference,
2868                                        base::Unretained(LeAudioClient::Get()), group_id,
2869                                        *preferred_codec_config_before_streaming,
2870                                        *preferred_codec_config_before_streaming));
2871       SyncOnMainLoop();
2872     }
2873 
2874     types::BidirectionalPair<std::vector<uint8_t>> ccids;
2875     constexpr int gmcs_ccid = 1;
2876     constexpr int gtbs_ccid = 2;
2877     if (context_type == LeAudioContextType::MEDIA) {
2878       ccids = types::BidirectionalPair<std::vector<uint8_t>>{{gmcs_ccid}, {}};
2879       EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, ccids)).Times(1);
2880       StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
2881     } else {
2882       ccids = types::BidirectionalPair<std::vector<uint8_t>>{{gtbs_ccid}, {gtbs_ccid}};
2883       EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, ccids)).Times(1);
2884       StartStreaming(AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_CONTENT_TYPE_SPEECH, group_id);
2885     }
2886     Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
2887     Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
2888 
2889     ASSERT_EQ(LeAudioClient::Get()->IsUsingPreferredCodecConfig(group_id,
2890                                                                 static_cast<int>(context_type)),
2891               is_using_set_before_streaming_codec_during_streaming);
2892 
2893     uint8_t cis_count_out = 2;
2894     uint8_t cis_count_in = context_type == LeAudioContextType::MEDIA ? 0 : 2;
2895     TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
2896 
2897     if (set_while_streaming) {
2898       EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(is_reconfig);
2899       EXPECT_CALL(*mock_le_audio_source_hal_client_, ReconfigurationComplete()).Times(is_reconfig);
2900 
2901       do_in_main_thread(base::BindOnce(&LeAudioClient::SetCodecConfigPreference,
2902                                        base::Unretained(LeAudioClient::Get()), group_id,
2903                                        *preferred_codec_config_during_streaming,
2904                                        *preferred_codec_config_during_streaming));
2905       SyncOnMainLoop();
2906       ASSERT_EQ(LeAudioClient::Get()->IsUsingPreferredCodecConfig(group_id,
2907                                                                   static_cast<int>(context_type)),
2908                 is_using_set_while_streaming_codec_during_streaming);
2909 
2910       if (context_type == LeAudioContextType::MEDIA) {
2911         ccids = types::BidirectionalPair<std::vector<uint8_t>>{{gmcs_ccid}, {}};
2912         EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, ccids)).Times(1);
2913         StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
2914       } else {
2915         ccids = types::BidirectionalPair<std::vector<uint8_t>>{{gtbs_ccid}, {gtbs_ccid}};
2916         EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, ccids)).Times(1);
2917         StartStreaming(AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_CONTENT_TYPE_SPEECH, group_id);
2918       }
2919     }
2920 
2921     StopStreaming(group_id, context_type == LeAudioContextType::CONVERSATIONAL);
2922     Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
2923     Mock::VerifyAndClearExpectations(&mock_state_machine_);
2924   }
2925 };
2926 
2927 class UnicastTestHealthStatus : public UnicastTest {
2928 protected:
SetUp()2929   void SetUp() override {
2930     UnicastTest::SetUp();
2931     group_ = new LeAudioDeviceGroup(group_id_);
2932   }
2933 
TearDown()2934   void TearDown() override {
2935     delete group_;
2936     UnicastTest::TearDown();
2937   }
2938 
2939   const int group_id_ = 0;
2940   LeAudioDeviceGroup* group_ = nullptr;
2941 };
2942 
2943 class UnicastTestHandoverMode : public UnicastTest {
2944 protected:
SetUp()2945   void SetUp() override {
2946     use_handover_mode = true;
2947     UnicastTest::SetUp();
2948     group_ = new LeAudioDeviceGroup(group_id_);
2949   }
2950 
TearDown()2951   void TearDown() override {
2952     delete group_;
2953     UnicastTest::TearDown();
2954   }
2955 
2956   const int group_id_ = 0;
2957   LeAudioDeviceGroup* group_ = nullptr;
2958 };
2959 
TEST_F(UnicastTest,Initialize)2960 TEST_F(UnicastTest, Initialize) {
2961   ASSERT_NE(LeAudioClient::Get(), nullptr);
2962   ASSERT_TRUE(LeAudioClient::IsLeAudioClientRunning());
2963 }
2964 
TEST_F(UnicastTestNoInit,InitializeNoHal_2_1)2965 TEST_F(UnicastTestNoInit, InitializeNoHal_2_1) {
2966   ASSERT_FALSE(LeAudioClient::IsLeAudioClientRunning());
2967 
2968   // Report False when asked for Audio HAL 2.1 support
2969   ON_CALL(mock_hal_2_1_verifier, Call()).WillByDefault([]() -> bool { return false; });
2970 
2971   BtaAppRegisterCallback app_register_callback;
2972   ON_CALL(mock_gatt_interface_, AppRegister(_, _, _))
2973           .WillByDefault(DoAll(SaveArg<0>(&gatt_callback), SaveArg<1>(&app_register_callback)));
2974   std::vector<::bluetooth::le_audio::btle_audio_codec_config_t> framework_encode_preference;
2975 
2976   EXPECT_DEATH(
2977           LeAudioClient::Initialize(
2978                   &mock_audio_hal_client_callbacks_,
2979                   base::Bind([](MockFunction<void()>* foo) { foo->Call(); }, &mock_storage_load),
2980                   base::Bind([](MockFunction<bool()>* foo) { return foo->Call(); },
2981                              &mock_hal_2_1_verifier),
2982                   framework_encode_preference),
2983           "LE Audio Client requires Bluetooth Audio HAL V2.1 at least. Either "
2984           "disable LE Audio Profile, or update your HAL");
2985 }
2986 
TEST_F(UnicastTest,CleanupWhenUserConnecting)2987 TEST_F(UnicastTest, CleanupWhenUserConnecting) {
2988   const RawAddress test_address0 = GetTestAddress(0);
2989   uint16_t conn_id = 1;
2990   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
2991                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
2992                                 default_channel_cnt, 0x0004,
2993                                 /* source sample freq 16khz */ true, /*add_csis*/
2994                                 true,                                /*add_cas*/
2995                                 true,                                /*add_pacs*/
2996                                 default_ase_cnt /*add_ascs*/);
2997 
2998   /* Remove default action on the direct connect */
2999   ON_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_DIRECT_CONNECTION, _)).WillByDefault(Return());
3000   ConnectLeAudio(test_address0, false, false);
3001 
3002   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, false)).Times(1);
3003   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, true)).Times(1);
3004   EXPECT_CALL(mock_btm_interface_, AclDisconnectFromHandle(conn_id, _)).Times(0);
3005   EXPECT_CALL(mock_gatt_interface_, Close(_)).Times(0);
3006 
3007   LeAudioClient::Cleanup();
3008   SyncOnMainLoop();
3009 
3010   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
3011 }
3012 
TEST_F(UnicastTest,CleanupWhenAutoConnecting)3013 TEST_F(UnicastTest, CleanupWhenAutoConnecting) {
3014   const RawAddress test_address0 = GetTestAddress(0);
3015   uint16_t conn_id = 1;
3016   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3017                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
3018                                 default_channel_cnt, 0x0004,
3019                                 /* source sample freq 16khz */ true, /*add_csis*/
3020                                 true,                                /*add_cas*/
3021                                 true,                                /*add_pacs*/
3022                                 default_ase_cnt /*add_ascs*/);
3023 
3024   log::info("Connect device");
3025   ConnectLeAudio(test_address0);
3026 
3027   /* Remove default action on the autoconnect */
3028   ON_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _))
3029           .WillByDefault(Return());
3030 
3031   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3032               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
3033           .Times(1);
3034   /* Make sure when remote device disconnects us, TA is used */
3035   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, _)).Times(1);
3036   EXPECT_CALL(mock_gatt_interface_,
3037               Open(gatt_if, test_address0, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _))
3038           .Times(1);
3039 
3040   InjectDisconnectedEvent(1, GATT_CONN_TERMINATE_PEER_USER);
3041   SyncOnMainLoop();
3042 
3043   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
3044 
3045   log::info("Device is in auto connect");
3046 
3047   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, false)).Times(1);
3048   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, true)).Times(0);
3049   EXPECT_CALL(mock_btm_interface_, AclDisconnectFromHandle(conn_id, _)).Times(0);
3050   EXPECT_CALL(mock_gatt_interface_, Close(_)).Times(0);
3051 
3052   LeAudioClient::Cleanup();
3053   SyncOnMainLoop();
3054 
3055   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
3056 }
3057 
TEST_F(UnicastTest,CleanupWhenConnected)3058 TEST_F(UnicastTest, CleanupWhenConnected) {
3059   const RawAddress test_address0 = GetTestAddress(0);
3060   uint16_t conn_id = 1;
3061   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3062                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
3063                                 default_channel_cnt, 0x0004,
3064                                 /* source sample freq 16khz */ true, /*add_csis*/
3065                                 true,                                /*add_cas*/
3066                                 true,                                /*add_pacs*/
3067                                 default_ase_cnt /*add_ascs*/);
3068 
3069   log::info("Connect device");
3070   ConnectLeAudio(test_address0);
3071 
3072   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, false)).Times(1);
3073   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, true)).Times(0);
3074   EXPECT_CALL(mock_btm_interface_, AclDisconnectFromHandle(conn_id, _)).Times(1);
3075   EXPECT_CALL(mock_gatt_interface_, Close(conn_id)).Times(1);
3076 
3077   LeAudioClient::Cleanup();
3078   SyncOnMainLoop();
3079 
3080   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
3081 }
3082 
TEST_F(UnicastTest,ConnectAndSetupPhy)3083 TEST_F(UnicastTest, ConnectAndSetupPhy) {
3084   const RawAddress test_address0 = GetTestAddress(0);
3085   uint16_t conn_id = 1;
3086   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3087                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
3088                                 default_channel_cnt, 0x0004,
3089                                 /* source sample freq 16khz */ true, /*add_csis*/
3090                                 true,                                /*add_cas*/
3091                                 true,                                /*add_pacs*/
3092                                 default_ase_cnt /*add_ascs*/);
3093 
3094   EXPECT_CALL(mock_btm_interface_, BleSetPhy(test_address0, PHY_LE_2M, PHY_LE_2M, 0)).Times(1);
3095   ConnectLeAudio(test_address0, false);
3096   Mock::VerifyAndClearExpectations(&mock_btm_interface_);
3097 
3098   EXPECT_CALL(mock_btm_interface_, BleSetPhy(test_address0, PHY_LE_2M, PHY_LE_2M, 0)).Times(1);
3099   InjectPhyChangedEvent(conn_id, 0, 0, GATT_REQ_NOT_SUPPORTED);
3100   SyncOnMainLoop();
3101   ON_CALL(mock_btm_interface_, BTM_IsEncrypted(test_address0, _))
3102           .WillByDefault(DoAll(Return(true)));
3103   InjectEncryptionChangedEvent(test_address0);
3104   SyncOnMainLoop();
3105   Mock::VerifyAndClearExpectations(&mock_btm_interface_);
3106 
3107   /* Make sure flag `acl_phy_update_done_` is cleared after disconnect.
3108    * Just repeat previous steps after reconnection
3109    */
3110   InjectDisconnectedEvent(conn_id);
3111   SyncOnMainLoop();
3112 
3113   EXPECT_CALL(mock_btm_interface_, BleSetPhy(test_address0, PHY_LE_2M, PHY_LE_2M, 0)).Times(1);
3114 
3115   ON_CALL(mock_btm_interface_, BTM_IsEncrypted(test_address0, _))
3116           .WillByDefault(DoAll(Return(false)));
3117   InjectConnectedEvent(test_address0, 1);
3118   SyncOnMainLoop();
3119   Mock::VerifyAndClearExpectations(&mock_btm_interface_);
3120 
3121   EXPECT_CALL(mock_btm_interface_, BleSetPhy(test_address0, PHY_LE_2M, PHY_LE_2M, 0)).Times(1);
3122   InjectPhyChangedEvent(conn_id, 0, 0, GATT_REQ_NOT_SUPPORTED);
3123   SyncOnMainLoop();
3124   ON_CALL(mock_btm_interface_, BTM_IsEncrypted(test_address0, _))
3125           .WillByDefault(DoAll(Return(true)));
3126   InjectEncryptionChangedEvent(test_address0);
3127   SyncOnMainLoop();
3128   Mock::VerifyAndClearExpectations(&mock_btm_interface_);
3129 }
3130 
TEST_F(UnicastTest,ConnectOneEarbudEmpty)3131 TEST_F(UnicastTest, ConnectOneEarbudEmpty) {
3132   const RawAddress test_address0 = GetTestAddress(0);
3133   SetSampleDatabaseEmpty(1, test_address0);
3134   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3135               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
3136           .Times(1);
3137   EXPECT_CALL(mock_gatt_interface_, Close(_)).Times(1);
3138   ConnectLeAudio(test_address0);
3139 }
3140 
TEST_F(UnicastTest,ConnectOneEarbudNoPacs)3141 TEST_F(UnicastTest, ConnectOneEarbudNoPacs) {
3142   const RawAddress test_address0 = GetTestAddress(0);
3143   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3144                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
3145                                 default_channel_cnt, 0x0004,
3146                                 /* source sample freq 16khz */ true, /*add_csis*/
3147                                 true,                                /*add_cas*/
3148                                 false,                               /*add_pacs*/
3149                                 default_ase_cnt /*add_ascs*/);
3150   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3151               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
3152           .Times(1);
3153   EXPECT_CALL(mock_gatt_interface_, Close(_)).Times(1);
3154   ConnectLeAudio(test_address0);
3155 }
3156 
TEST_F(UnicastTest,ConnectOneEarbudNoAscs)3157 TEST_F(UnicastTest, ConnectOneEarbudNoAscs) {
3158   const RawAddress test_address0 = GetTestAddress(0);
3159   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3160                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
3161                                 default_channel_cnt, 0x0004,
3162                                 /* source sample freq 16khz */ true, /*add_csis*/
3163                                 true,                                /*add_cas*/
3164                                 true,                                /*add_pacs*/
3165                                 0 /*add_ascs*/);
3166   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3167               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
3168           .Times(1);
3169   EXPECT_CALL(mock_gatt_interface_, Close(_)).Times(1);
3170   ConnectLeAudio(test_address0);
3171 }
3172 
TEST_F(UnicastTest,ConnectOneEarbudNoCas)3173 TEST_F(UnicastTest, ConnectOneEarbudNoCas) {
3174   const RawAddress test_address0 = GetTestAddress(0);
3175   uint16_t conn_id = 1;
3176   SetSampleDatabaseEarbudsValid(conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3177                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
3178                                 default_channel_cnt, 0x0004,
3179                                 /* source sample freq 16khz */ true, /*add_csis*/
3180                                 false,                               /*add_cas*/
3181                                 true,                                /*add_pacs*/
3182                                 default_ase_cnt /*add_ascs*/);
3183 
3184   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3185               OnConnectionState(ConnectionState::CONNECTED, test_address0))
3186           .Times(1);
3187   ConnectLeAudio(test_address0);
3188 }
3189 
TEST_F(UnicastTest,ConnectOneEarbudNoCsis)3190 TEST_F(UnicastTest, ConnectOneEarbudNoCsis) {
3191   const RawAddress test_address0 = GetTestAddress(0);
3192   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3193                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
3194                                 default_channel_cnt, 0x0004,
3195                                 /* source sample freq 16khz */ false, /*add_csis*/
3196                                 true,                                 /*add_cas*/
3197                                 true,                                 /*add_pacs*/
3198                                 default_ase_cnt /*add_ascs*/);
3199   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3200               OnConnectionState(ConnectionState::CONNECTED, test_address0))
3201           .Times(1);
3202   ConnectLeAudio(test_address0);
3203 }
3204 
TEST_F(UnicastTest,ConnectOneEarbudWithInvalidCsis)3205 TEST_F(UnicastTest, ConnectOneEarbudWithInvalidCsis) {
3206   const RawAddress test_address0 = GetTestAddress(0);
3207   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3208                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
3209                                 default_channel_cnt, 0x0004,
3210                                 /* source sample freq 16khz */ true, /*add_csis*/
3211                                 true,                                /*add_cas*/
3212                                 true,                                /*add_pacs*/
3213                                 default_ase_cnt /*add_ascs*/);
3214   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3215               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
3216           .Times(1);
3217   EXPECT_CALL(mock_gatt_interface_, Close(_)).Times(1);
3218 
3219   // Report working CSIS
3220   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
3221 
3222   /* Make sure Group has not knowledge about the device */
3223   ON_CALL(mock_groups_module_, GetGroupId(_, _))
3224           .WillByDefault([](const RawAddress& /*addr*/, bluetooth::Uuid /*uuid*/) {
3225             return bluetooth::groups::kGroupUnknown;
3226           });
3227 
3228   ConnectLeAudio(test_address0);
3229   SyncOnMainLoop();
3230   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
3231   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3232 }
3233 
TEST_F(UnicastTestHealthStatus,ConnectOneEarbudEmpty_withHealthStatus)3234 TEST_F(UnicastTestHealthStatus, ConnectOneEarbudEmpty_withHealthStatus) {
3235   const RawAddress test_address0 = GetTestAddress(0);
3236   SetSampleDatabaseEmpty(1, test_address0);
3237   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3238               OnHealthBasedRecommendationAction(test_address0, LeAudioHealthBasedAction::DISABLE))
3239           .Times(1);
3240   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3241               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
3242           .Times(1);
3243   EXPECT_CALL(mock_gatt_interface_, Close(_)).Times(1);
3244   ConnectLeAudio(test_address0);
3245   SyncOnMainLoop();
3246   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3247   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
3248 
3249   LeAudioHealthStatus::Get()->RemoveStatistics(test_address0, bluetooth::groups::kGroupUnknown);
3250 }
3251 
TEST_F(UnicastTestHealthStatus,ConnectOneEarbudNoPacs_withHealthStatus)3252 TEST_F(UnicastTestHealthStatus, ConnectOneEarbudNoPacs_withHealthStatus) {
3253   const RawAddress test_address0 = GetTestAddress(0);
3254   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3255                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
3256                                 default_channel_cnt, 0x0004,
3257                                 /* source sample freq 16khz */ true, /*add_csis*/
3258                                 true,                                /*add_cas*/
3259                                 false,                               /*add_pacs*/
3260                                 default_ase_cnt /*add_ascs*/);
3261   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3262               OnHealthBasedRecommendationAction(test_address0, LeAudioHealthBasedAction::DISABLE))
3263           .Times(1);
3264   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3265               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
3266           .Times(1);
3267   EXPECT_CALL(mock_gatt_interface_, Close(_)).Times(1);
3268   ConnectLeAudio(test_address0);
3269   SyncOnMainLoop();
3270   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3271   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
3272 
3273   LeAudioHealthStatus::Get()->RemoveStatistics(test_address0, bluetooth::groups::kGroupUnknown);
3274 }
3275 
TEST_F(UnicastTestHealthStatus,ConnectOneEarbudNoAscs_withHealthStatus)3276 TEST_F(UnicastTestHealthStatus, ConnectOneEarbudNoAscs_withHealthStatus) {
3277   const RawAddress test_address0 = GetTestAddress(0);
3278   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3279                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
3280                                 default_channel_cnt, 0x0004,
3281                                 /* source sample freq 16khz */ true, /*add_csis*/
3282                                 true,                                /*add_cas*/
3283                                 true,                                /*add_pacs*/
3284                                 0 /*add_ascs*/);
3285   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3286               OnHealthBasedRecommendationAction(test_address0, LeAudioHealthBasedAction::DISABLE))
3287           .Times(1);
3288   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3289               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
3290           .Times(1);
3291   EXPECT_CALL(mock_gatt_interface_, Close(_)).Times(1);
3292   ConnectLeAudio(test_address0);
3293   SyncOnMainLoop();
3294   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3295   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
3296 
3297   LeAudioHealthStatus::Get()->RemoveStatistics(test_address0, bluetooth::groups::kGroupUnknown);
3298 }
3299 
TEST_F(UnicastTestHealthStatus,ConnectOneEarbudNoCas_withHealthStatus)3300 TEST_F(UnicastTestHealthStatus, ConnectOneEarbudNoCas_withHealthStatus) {
3301   const RawAddress test_address0 = GetTestAddress(0);
3302   uint16_t conn_id = 1;
3303   SetSampleDatabaseEarbudsValid(conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3304                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
3305                                 default_channel_cnt, 0x0004,
3306                                 /* source sample freq 16khz */ true, /*add_csis*/
3307                                 false,                               /*add_cas*/
3308                                 true,                                /*add_pacs*/
3309                                 default_ase_cnt /*add_ascs*/);
3310 
3311   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3312               OnHealthBasedRecommendationAction(test_address0, LeAudioHealthBasedAction::DISABLE))
3313           .Times(0);
3314   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3315               OnConnectionState(ConnectionState::CONNECTED, test_address0))
3316           .Times(1);
3317   ConnectLeAudio(test_address0);
3318   SyncOnMainLoop();
3319   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3320 
3321   LeAudioHealthStatus::Get()->RemoveStatistics(test_address0, bluetooth::groups::kGroupUnknown);
3322 }
3323 
TEST_F(UnicastTestHealthStatus,ConnectOneEarbudNoCsis_withHealthStatus)3324 TEST_F(UnicastTestHealthStatus, ConnectOneEarbudNoCsis_withHealthStatus) {
3325   const RawAddress test_address0 = GetTestAddress(0);
3326   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3327                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
3328                                 default_channel_cnt, 0x0004,
3329                                 /* source sample freq 16khz */ false, /*add_csis*/
3330                                 true,                                 /*add_cas*/
3331                                 true,                                 /*add_pacs*/
3332                                 default_ase_cnt /*add_ascs*/);
3333   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3334               OnHealthBasedRecommendationAction(test_address0, LeAudioHealthBasedAction::DISABLE))
3335           .Times(0);
3336   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3337               OnConnectionState(ConnectionState::CONNECTED, test_address0))
3338           .Times(1);
3339   ConnectLeAudio(test_address0);
3340   SyncOnMainLoop();
3341   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3342 
3343   LeAudioHealthStatus::Get()->RemoveStatistics(test_address0, bluetooth::groups::kGroupUnknown);
3344 }
3345 
TEST_F(UnicastTestHealthStatus,ConnectOneEarbudWithInvalidCsis_withHealthStatus)3346 TEST_F(UnicastTestHealthStatus, ConnectOneEarbudWithInvalidCsis_withHealthStatus) {
3347   const RawAddress test_address0 = GetTestAddress(0);
3348   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3349                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
3350                                 default_channel_cnt, 0x0004,
3351                                 /* source sample freq 16khz */ true, /*add_csis*/
3352                                 true,                                /*add_cas*/
3353                                 true,                                /*add_pacs*/
3354                                 default_ase_cnt /*add_ascs*/);
3355   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3356               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
3357           .Times(1);
3358   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3359               OnHealthBasedRecommendationAction(test_address0, LeAudioHealthBasedAction::DISABLE))
3360           .Times(1);
3361 
3362   EXPECT_CALL(mock_gatt_interface_, Close(_)).Times(1);
3363 
3364   // Report working CSIS
3365   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
3366 
3367   /* Make sure Group has not knowledge about the device */
3368   ON_CALL(mock_groups_module_, GetGroupId(_, _))
3369           .WillByDefault([](const RawAddress& /*addr*/, bluetooth::Uuid /*uuid*/) {
3370             return bluetooth::groups::kGroupUnknown;
3371           });
3372 
3373   ConnectLeAudio(test_address0);
3374   SyncOnMainLoop();
3375   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
3376   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3377 
3378   LeAudioHealthStatus::Get()->RemoveStatistics(test_address0, bluetooth::groups::kGroupUnknown);
3379 }
3380 
TEST_F(UnicastTestHealthStatus,ConnectOneEarbudDisable_withHealthStatus)3381 TEST_F(UnicastTestHealthStatus, ConnectOneEarbudDisable_withHealthStatus) {
3382   const RawAddress test_address0 = GetTestAddress(0);
3383   int conn_id = 1;
3384 
3385   SetSampleDatabaseEarbudsValid(conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3386                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
3387                                 default_channel_cnt, 0x0004, false);
3388   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3389               OnConnectionState(ConnectionState::CONNECTED, test_address0))
3390           .Times(1);
3391 
3392   ConnectLeAudio(test_address0);
3393   SyncOnMainLoop();
3394   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3395 
3396   LeAudioClient::Get()->GroupSetActive(group_id_);
3397   auto device = std::make_shared<LeAudioDevice>(test_address0, DeviceConnectState::DISCONNECTED);
3398   group_->AddNode(device);
3399   SyncOnMainLoop();
3400 
3401   auto health_status = LeAudioHealthStatus::Get();
3402 
3403   /* Inject stream error */
3404   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3405               OnHealthBasedGroupRecommendationAction(group_id_, LeAudioHealthBasedAction::DISABLE))
3406           .Times(1);
3407   health_status->AddStatisticForGroup(group_, LeAudioHealthGroupStatType::STREAM_CREATE_CIS_FAILED);
3408   health_status->AddStatisticForGroup(group_, LeAudioHealthGroupStatType::STREAM_CREATE_CIS_FAILED);
3409 
3410   /* Do not act on disconnect */
3411   ON_CALL(mock_gatt_interface_, Close(_)).WillByDefault(DoAll(Return()));
3412   ON_CALL(mock_btm_interface_, AclDisconnectFromHandle(_, _)).WillByDefault(DoAll(Return()));
3413 
3414   state_machine_callbacks_->OnStateTransitionTimeout(group_id_);
3415   SyncOnMainLoop();
3416   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3417 
3418   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3419               OnHealthBasedGroupRecommendationAction(group_id_, LeAudioHealthBasedAction::DISABLE))
3420           .Times(0);
3421   health_status->AddStatisticForGroup(group_, LeAudioHealthGroupStatType::STREAM_CREATE_CIS_FAILED);
3422   health_status->AddStatisticForGroup(group_, LeAudioHealthGroupStatType::STREAM_CREATE_CIS_FAILED);
3423   SyncOnMainLoop();
3424   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3425 }
3426 
TEST_F(UnicastTestHealthStatus,ConnectOneEarbudConsiderDisabling_withHealthStatus)3427 TEST_F(UnicastTestHealthStatus, ConnectOneEarbudConsiderDisabling_withHealthStatus) {
3428   const RawAddress test_address0 = GetTestAddress(0);
3429   int conn_id = 1;
3430 
3431   SetSampleDatabaseEarbudsValid(conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3432                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
3433                                 default_channel_cnt, 0x0004, false);
3434   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3435               OnConnectionState(ConnectionState::CONNECTED, test_address0))
3436           .Times(1);
3437 
3438   ConnectLeAudio(test_address0);
3439   SyncOnMainLoop();
3440   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3441 
3442   LeAudioClient::Get()->GroupSetActive(group_id_);
3443   auto device = std::make_shared<LeAudioDevice>(test_address0, DeviceConnectState::DISCONNECTED);
3444   group_->AddNode(device);
3445   SyncOnMainLoop();
3446 
3447   auto health_status = LeAudioHealthStatus::Get();
3448 
3449   /* Inject stream success and error */
3450   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3451               OnHealthBasedGroupRecommendationAction(group_id_,
3452                                                      LeAudioHealthBasedAction::CONSIDER_DISABLING))
3453           .Times(1);
3454   health_status->AddStatisticForGroup(group_, LeAudioHealthGroupStatType::STREAM_CREATE_SUCCESS);
3455   health_status->AddStatisticForGroup(group_, LeAudioHealthGroupStatType::STREAM_CREATE_CIS_FAILED);
3456   health_status->AddStatisticForGroup(group_, LeAudioHealthGroupStatType::STREAM_CREATE_CIS_FAILED);
3457 
3458   /* Do not act on disconnect */
3459   ON_CALL(mock_gatt_interface_, Close(_)).WillByDefault(DoAll(Return()));
3460   ON_CALL(mock_btm_interface_, AclDisconnectFromHandle(_, _)).WillByDefault(DoAll(Return()));
3461 
3462   state_machine_callbacks_->OnStateTransitionTimeout(group_id_);
3463   SyncOnMainLoop();
3464   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3465 
3466   EXPECT_CALL(
3467           mock_audio_hal_client_callbacks_,
3468           OnHealthBasedGroupRecommendationAction(1, LeAudioHealthBasedAction::CONSIDER_DISABLING))
3469           .Times(0);
3470   health_status->AddStatisticForGroup(group_, LeAudioHealthGroupStatType::STREAM_CREATE_CIS_FAILED);
3471   health_status->AddStatisticForGroup(group_, LeAudioHealthGroupStatType::STREAM_CREATE_CIS_FAILED);
3472   SyncOnMainLoop();
3473   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3474 }
3475 
TEST_F(UnicastTest,ConnectDisconnectOneEarbud)3476 TEST_F(UnicastTest, ConnectDisconnectOneEarbud) {
3477   const RawAddress test_address0 = GetTestAddress(0);
3478   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3479                                 codec_spec_conf::kLeAudioLocationStereo);
3480   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3481               OnConnectionState(ConnectionState::CONNECTED, test_address0))
3482           .Times(1);
3483   ConnectLeAudio(test_address0);
3484   DisconnectLeAudioWithAclClose(test_address0, 1);
3485 }
3486 
TEST_F(UnicastTest,ConnectRemoteServiceDiscoveryCompleteBeforeEncryption)3487 TEST_F(UnicastTest, ConnectRemoteServiceDiscoveryCompleteBeforeEncryption) {
3488   const RawAddress test_address0 = GetTestAddress(0);
3489   uint16_t conn_id = 1;
3490   SetSampleDatabaseEarbudsValid(conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3491                                 codec_spec_conf::kLeAudioLocationStereo);
3492   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3493               OnConnectionState(ConnectionState::CONNECTED, test_address0))
3494           .Times(0);
3495   ConnectLeAudio(test_address0, false);
3496   InjectSearchCompleteEvent(conn_id);
3497 
3498   SyncOnMainLoop();
3499   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3500 
3501   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3502               OnConnectionState(ConnectionState::CONNECTED, test_address0))
3503           .Times(1);
3504   ON_CALL(mock_btm_interface_, BTM_IsEncrypted(test_address0, _))
3505           .WillByDefault(DoAll(Return(true)));
3506   InjectEncryptionChangedEvent(test_address0);
3507   SyncOnMainLoop();
3508   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3509 }
3510 
TEST_F(UnicastTest,DisconnectWhenLinkKeyIsGone)3511 TEST_F(UnicastTest, DisconnectWhenLinkKeyIsGone) {
3512   const RawAddress test_address0 = GetTestAddress(0);
3513   uint16_t conn_id = 1;
3514   SetSampleDatabaseEarbudsValid(conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3515                                 codec_spec_conf::kLeAudioLocationStereo);
3516   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3517               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
3518           .Times(1);
3519 
3520   ON_CALL(mock_btm_interface_, BTM_IsEncrypted(test_address0, _))
3521           .WillByDefault(DoAll(Return(false)));
3522 
3523   ON_CALL(mock_btm_interface_, SetEncryption(test_address0, _, _, _, _))
3524           .WillByDefault(Return(tBTM_STATUS::BTM_ERR_KEY_MISSING));
3525 
3526   EXPECT_CALL(mock_gatt_interface_, Close(conn_id)).Times(1);
3527   do_in_main_thread(base::BindOnce(&LeAudioClient::Connect, base::Unretained(LeAudioClient::Get()),
3528                                    test_address0));
3529 
3530   SyncOnMainLoop();
3531   Mock::VerifyAndClearExpectations(&mock_btm_interface_);
3532   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
3533 }
3534 
3535 /* same as above case except the disconnect is initiated by remote */
TEST_F(UnicastTest,ConnectRemoteDisconnectOneEarbud)3536 TEST_F(UnicastTest, ConnectRemoteDisconnectOneEarbud) {
3537   const RawAddress test_address0 = GetTestAddress(0);
3538   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3539                                 codec_spec_conf::kLeAudioLocationStereo);
3540   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3541               OnConnectionState(ConnectionState::CONNECTED, test_address0))
3542           .Times(1);
3543   ConnectLeAudio(test_address0);
3544   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
3545 
3546   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3547               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
3548           .Times(1);
3549   /* Make sure when remote device disconnects us, TA is used */
3550   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, _)).Times(1);
3551   EXPECT_CALL(mock_gatt_interface_,
3552               Open(gatt_if, test_address0, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _))
3553           .Times(1);
3554 
3555   InjectDisconnectedEvent(1, GATT_CONN_TERMINATE_PEER_USER);
3556   SyncOnMainLoop();
3557 
3558   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
3559 
3560   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3561               OnConnectionState(ConnectionState::CONNECTED, test_address0))
3562           .Times(1);
3563 
3564   /* When reconnected, we always remove background connect, as we do not track
3565    * which type (allow list or TA) was used and then make sure the TA is used.
3566    */
3567   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, _)).Times(1);
3568   EXPECT_CALL(mock_gatt_interface_,
3569               Open(gatt_if, test_address0, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _))
3570           .Times(1);
3571 
3572   /* For background connect, test needs to Inject Connected Event */
3573   InjectConnectedEvent(test_address0, 1);
3574   SyncOnMainLoop();
3575   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
3576 }
3577 
3578 /* same as above case except the disconnect is initiated by remote */
TEST_F(UnicastTest,ConnectRemoteDisconnectOnTimeoutOneEarbud)3579 TEST_F(UnicastTest, ConnectRemoteDisconnectOnTimeoutOneEarbud) {
3580   const RawAddress test_address0 = GetTestAddress(0);
3581   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3582                                 codec_spec_conf::kLeAudioLocationStereo);
3583   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3584               OnConnectionState(ConnectionState::CONNECTED, test_address0))
3585           .Times(1);
3586   ConnectLeAudio(test_address0);
3587   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3588               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
3589           .Times(1);
3590 
3591   /* Remove default action on the direct connect */
3592   ON_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_DIRECT_CONNECTION, _)).WillByDefault(Return());
3593 
3594   /* For remote disconnection, expect stack to try background re-connect */
3595   EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address0, BTM_BLE_DIRECT_CONNECTION, _))
3596           .Times(1);
3597 
3598   InjectDisconnectedEvent(1, GATT_CONN_TIMEOUT);
3599   SyncOnMainLoop();
3600 
3601   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
3602 
3603   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3604               OnConnectionState(ConnectionState::CONNECTED, test_address0))
3605           .Times(1);
3606 
3607   /* For background connect, test needs to Inject Connected Event */
3608   InjectConnectedEvent(test_address0, 1);
3609   SyncOnMainLoop();
3610 }
3611 
TEST_F(UnicastTest,ConnectTwoEarbudsCsisGrouped)3612 TEST_F(UnicastTest, ConnectTwoEarbudsCsisGrouped) {
3613   uint8_t group_size = 2;
3614   int group_id = 2;
3615 
3616   // Report working CSIS
3617   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
3618 
3619   // First earbud
3620   const RawAddress test_address0 = GetTestAddress(0);
3621   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
3622   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
3623                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
3624 
3625   // Second earbud
3626   const RawAddress test_address1 = GetTestAddress(1);
3627   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
3628   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
3629                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
3630                     true /*connect_through_csis*/);
3631 
3632   Mock::VerifyAndClearExpectations(&mock_btif_storage_);
3633 
3634   /* for Target announcements AutoConnect is always there, until
3635    * device is removed
3636    */
3637   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, false)).Times(0);
3638   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, false)).Times(0);
3639 
3640   // Verify grouping information
3641   std::vector<RawAddress> devs = LeAudioClient::Get()->GetGroupDevices(group_id);
3642   ASSERT_NE(std::find(devs.begin(), devs.end(), test_address0), devs.end());
3643   ASSERT_NE(std::find(devs.begin(), devs.end(), test_address1), devs.end());
3644 
3645   DisconnectLeAudioWithAclClose(test_address0, 1);
3646   DisconnectLeAudioWithAclClose(test_address1, 2);
3647 }
3648 
TEST_F(UnicastTest,ConnectTwoEarbudsCsisGroupUnknownAtConnect)3649 TEST_F(UnicastTest, ConnectTwoEarbudsCsisGroupUnknownAtConnect) {
3650   uint8_t group_size = 2;
3651   uint8_t group_id = 2;
3652 
3653   // Report working CSIS
3654   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
3655 
3656   // First earbud connects without known grouping
3657   const RawAddress test_address0 = GetTestAddress(0);
3658   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
3659   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
3660                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
3661 
3662   // Second earbud
3663   const RawAddress test_address1 = GetTestAddress(1);
3664   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
3665   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
3666                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
3667                     true /*connect_through_csis*/);
3668 
3669   Mock::VerifyAndClearExpectations(&mock_btif_storage_);
3670 
3671   // Verify grouping information
3672   std::vector<RawAddress> devs = LeAudioClient::Get()->GetGroupDevices(group_id);
3673   ASSERT_NE(std::find(devs.begin(), devs.end(), test_address0), devs.end());
3674   ASSERT_NE(std::find(devs.begin(), devs.end(), test_address1), devs.end());
3675 
3676   /* for Target announcements AutoConnect is always there, until
3677    *  device is removed
3678    */
3679   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, false)).Times(0);
3680   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, false)).Times(0);
3681   DisconnectLeAudioWithAclClose(test_address0, 1);
3682   DisconnectLeAudioWithAclClose(test_address1, 2);
3683 }
3684 
TEST_F(UnicastTestNoInit,ConnectFailedDueToInvalidParameters)3685 TEST_F(UnicastTestNoInit, ConnectFailedDueToInvalidParameters) {
3686   // Prepare two devices
3687   uint8_t group_size = 2;
3688   uint8_t group_id = 2;
3689 
3690   /* Prepare  mock to not inject connect event so the device can stay in
3691    * CONNECTING state*/
3692   ON_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_DIRECT_CONNECTION, false))
3693           .WillByDefault(DoAll(Return()));
3694 
3695   const RawAddress test_address0 = GetTestAddress(0);
3696   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationFrontLeft,
3697                                 codec_spec_conf::kLeAudioLocationFrontLeft, default_channel_cnt,
3698                                 default_channel_cnt, 0x0004,
3699                                 /* source sample freq 16khz */ true, /*add_csis*/
3700                                 true,                                /*add_cas*/
3701                                 true,                                /*add_pacs*/
3702                                 default_ase_cnt,                     /*add_ascs_cnt*/
3703                                 group_size, 1);
3704 
3705   const RawAddress test_address1 = GetTestAddress(1);
3706   SetSampleDatabaseEarbudsValid(2, test_address1, codec_spec_conf::kLeAudioLocationFrontRight,
3707                                 codec_spec_conf::kLeAudioLocationFrontRight, default_channel_cnt,
3708                                 default_channel_cnt, 0x0004,
3709                                 /* source sample freq 16khz */ true, /*add_csis*/
3710                                 true,                                /*add_cas*/
3711                                 true,                                /*add_pacs*/
3712                                 default_ase_cnt,                     /*add_ascs_cnt*/
3713                                 group_size, 2);
3714 
3715   // Load devices from the storage when storage API is called
3716   bool autoconnect = true;
3717 
3718   /* Common storage values */
3719   std::vector<uint8_t> handles;
3720   LeAudioClient::GetHandlesForStorage(test_address0, handles);
3721 
3722   std::vector<uint8_t> ases;
3723   LeAudioClient::GetAsesForStorage(test_address0, ases);
3724 
3725   std::vector<uint8_t> src_pacs;
3726   LeAudioClient::GetSourcePacsForStorage(test_address0, src_pacs);
3727 
3728   std::vector<uint8_t> snk_pacs;
3729   LeAudioClient::GetSinkPacsForStorage(test_address0, snk_pacs);
3730 
3731   EXPECT_CALL(mock_storage_load, Call()).WillOnce([&]() {
3732     do_in_main_thread(base::Bind(&LeAudioClient::AddFromStorage, test_address0, autoconnect,
3733                                  codec_spec_conf::kLeAudioLocationFrontLeft,
3734                                  codec_spec_conf::kLeAudioLocationFrontLeft, 0xff, 0xff,
3735                                  std::move(handles), std::move(snk_pacs), std::move(src_pacs),
3736                                  std::move(ases)));
3737     do_in_main_thread(base::Bind(&LeAudioClient::AddFromStorage, test_address1, autoconnect,
3738                                  codec_spec_conf::kLeAudioLocationFrontRight,
3739                                  codec_spec_conf::kLeAudioLocationFrontRight, 0xff, 0xff,
3740                                  std::move(handles), std::move(snk_pacs), std::move(src_pacs),
3741                                  std::move(ases)));
3742   });
3743 
3744   // Expect stored device0 to connect automatically (first directed connection )
3745   EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address0, BTM_BLE_DIRECT_CONNECTION, _))
3746           .Times(1);
3747 
3748   // Expect stored device1 to connect automatically (first direct connection)
3749   EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address1, BTM_BLE_DIRECT_CONNECTION, _))
3750           .Times(1);
3751 
3752   ON_CALL(mock_btm_interface_, BTM_IsEncrypted(test_address1, _))
3753           .WillByDefault(DoAll(Return(true)));
3754   ON_CALL(mock_btm_interface_, BTM_IsEncrypted(test_address0, _))
3755           .WillByDefault(DoAll(Return(true)));
3756 
3757   ON_CALL(mock_groups_module_, GetGroupId(_, _)).WillByDefault(DoAll(Return(group_id)));
3758 
3759   ON_CALL(mock_btm_interface_, GetSecurityFlagsByTransport(test_address0, NotNull(), _))
3760           .WillByDefault(DoAll(SetArgPointee<1>(BTM_SEC_FLAG_ENCRYPTED), Return(true)));
3761 
3762   std::vector<::bluetooth::le_audio::btle_audio_codec_config_t> framework_encode_preference;
3763 
3764   // Initialize
3765   BtaAppRegisterCallback app_register_callback;
3766   ON_CALL(mock_gatt_interface_, AppRegister(_, _, _))
3767           .WillByDefault(DoAll(SaveArg<0>(&gatt_callback), SaveArg<1>(&app_register_callback)));
3768   LeAudioClient::Initialize(
3769           &mock_audio_hal_client_callbacks_,
3770           base::Bind([](MockFunction<void()>* foo) { foo->Call(); }, &mock_storage_load),
3771           base::Bind([](MockFunction<bool()>* foo) { return foo->Call(); }, &mock_hal_2_1_verifier),
3772           framework_encode_preference);
3773   if (app_register_callback) {
3774     app_register_callback.Run(gatt_if, GATT_SUCCESS);
3775   }
3776 
3777   // We need to wait for the storage callback before verifying stuff
3778   SyncOnMainLoop();
3779   ASSERT_TRUE(LeAudioClient::IsLeAudioClientRunning());
3780   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
3781 
3782   // Simulate connect parameters are invalid and phone does not fallback
3783   // to background connect.
3784   EXPECT_CALL(mock_gatt_interface_,
3785               Open(gatt_if, test_address0, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _))
3786           .Times(0);
3787 
3788   EXPECT_CALL(mock_gatt_interface_,
3789               Open(gatt_if, test_address1, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _))
3790           .Times(0);
3791 
3792   // Devices not found
3793   InjectConnectedEvent(test_address0, 0, GATT_ILLEGAL_PARAMETER);
3794   InjectConnectedEvent(test_address1, 0, GATT_ILLEGAL_PARAMETER);
3795 
3796   SyncOnMainLoop();
3797   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
3798 }
3799 
TEST_F(UnicastTestNoInit,LoadStoredEarbudsBroakenStorage)3800 TEST_F(UnicastTestNoInit, LoadStoredEarbudsBroakenStorage) {
3801   // Prepare two devices
3802   uint8_t group_size = 2;
3803   uint8_t group_id = 2;
3804   /* If the storage has been broken, make sure device will be rediscovered after
3805    * reconnection
3806    */
3807 
3808   /* Prepare  mock to not inject connect event so the device can stay in
3809    * CONNECTING state*/
3810   ON_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_DIRECT_CONNECTION, false))
3811           .WillByDefault(DoAll(Return()));
3812 
3813   const RawAddress test_address0 = GetTestAddress(0);
3814   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationFrontLeft,
3815                                 codec_spec_conf::kLeAudioLocationFrontLeft, default_channel_cnt,
3816                                 default_channel_cnt, 0x0004,
3817                                 /* source sample freq 16khz */ true, /*add_csis*/
3818                                 true,                                /*add_cas*/
3819                                 true,                                /*add_pacs*/
3820                                 default_ase_cnt,                     /*add_ascs_cnt*/
3821                                 group_size, 1);
3822 
3823   const RawAddress test_address1 = GetTestAddress(1);
3824   SetSampleDatabaseEarbudsValid(2, test_address1, codec_spec_conf::kLeAudioLocationFrontRight,
3825                                 codec_spec_conf::kLeAudioLocationFrontRight, default_channel_cnt,
3826                                 default_channel_cnt, 0x0004,
3827                                 /* source sample freq 16khz */ true, /*add_csis*/
3828                                 true,                                /*add_cas*/
3829                                 true,                                /*add_pacs*/
3830                                 default_ase_cnt,                     /*add_ascs_cnt*/
3831                                 group_size, 2);
3832 
3833   // Load devices from the storage when storage API is called
3834   bool autoconnect = true;
3835   std::vector<uint8_t> empty_buf;
3836 
3837   EXPECT_CALL(mock_storage_load, Call()).WillOnce([&]() {
3838     do_in_main_thread(base::BindOnce(&LeAudioClient::AddFromStorage, test_address0, autoconnect,
3839                                      codec_spec_conf::kLeAudioLocationFrontLeft,
3840                                      codec_spec_conf::kLeAudioLocationFrontLeft, 0xff, 0xff,
3841                                      std::move(empty_buf), std::move(empty_buf),
3842                                      std::move(empty_buf), std::move(empty_buf)));
3843     do_in_main_thread(base::BindOnce(&LeAudioClient::AddFromStorage, test_address1, autoconnect,
3844                                      codec_spec_conf::kLeAudioLocationFrontRight,
3845                                      codec_spec_conf::kLeAudioLocationFrontRight, 0xff, 0xff,
3846                                      std::move(empty_buf), std::move(empty_buf),
3847                                      std::move(empty_buf), std::move(empty_buf)));
3848     SyncOnMainLoop();
3849   });
3850 
3851   // Expect stored device0 to connect automatically (first directed connection )
3852   EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address0, BTM_BLE_DIRECT_CONNECTION, _))
3853           .Times(1);
3854 
3855   // Expect stored device1 to connect automatically (first direct connection)
3856   EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address1, BTM_BLE_DIRECT_CONNECTION, _))
3857           .Times(1);
3858 
3859   ON_CALL(mock_btm_interface_, BTM_IsEncrypted(test_address1, _))
3860           .WillByDefault(DoAll(Return(true)));
3861   ON_CALL(mock_btm_interface_, BTM_IsEncrypted(test_address0, _))
3862           .WillByDefault(DoAll(Return(true)));
3863 
3864   ON_CALL(mock_groups_module_, GetGroupId(_, _)).WillByDefault(DoAll(Return(group_id)));
3865 
3866   ON_CALL(mock_btm_interface_, GetSecurityFlagsByTransport(test_address0, NotNull(), _))
3867           .WillByDefault(DoAll(SetArgPointee<1>(BTM_SEC_FLAG_ENCRYPTED), Return(true)));
3868 
3869   std::vector<::bluetooth::le_audio::btle_audio_codec_config_t> framework_encode_preference;
3870 
3871   // Initialize
3872   BtaAppRegisterCallback app_register_callback;
3873   ON_CALL(mock_gatt_interface_, AppRegister(_, _, _))
3874           .WillByDefault(DoAll(SaveArg<0>(&gatt_callback), SaveArg<1>(&app_register_callback)));
3875   LeAudioClient::Initialize(
3876           &mock_audio_hal_client_callbacks_,
3877           base::Bind([](MockFunction<void()>* foo) { foo->Call(); }, &mock_storage_load),
3878           base::Bind([](MockFunction<bool()>* foo) { return foo->Call(); }, &mock_hal_2_1_verifier),
3879           framework_encode_preference);
3880   if (app_register_callback) {
3881     app_register_callback.Run(gatt_if, GATT_SUCCESS);
3882   }
3883 
3884   // We need to wait for the storage callback before verifying stuff
3885   SyncOnMainLoop();
3886   ASSERT_TRUE(LeAudioClient::IsLeAudioClientRunning());
3887   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
3888 
3889   // Simulate devices are not there and phone fallbacks to targeted
3890   // announcements
3891   EXPECT_CALL(mock_gatt_interface_,
3892               Open(gatt_if, test_address0, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _))
3893           .Times(1);
3894 
3895   EXPECT_CALL(mock_gatt_interface_,
3896               Open(gatt_if, test_address1, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _))
3897           .Times(1);
3898 
3899   // Devices not found
3900   InjectConnectedEvent(test_address0, 0, GATT_ERROR);
3901   InjectConnectedEvent(test_address1, 0, GATT_ERROR);
3902 
3903   SyncOnMainLoop();
3904   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
3905 
3906   /* Stack should rediscover services as storage is broken */
3907   EXPECT_CALL(mock_gatt_interface_, ServiceSearchRequest(2, _)).Times(1);
3908   EXPECT_CALL(mock_gatt_interface_, ServiceSearchRequest(1, _)).Times(1);
3909 
3910   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3911               OnConnectionState(ConnectionState::CONNECTED, test_address0))
3912           .Times(1);
3913 
3914   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3915               OnConnectionState(ConnectionState::CONNECTED, test_address1))
3916           .Times(1);
3917 
3918   /* For background connect, test needs to Inject Connected Event */
3919   InjectConnectedEvent(test_address0, 1);
3920   InjectConnectedEvent(test_address1, 2);
3921   SyncOnMainLoop();
3922 
3923   // Verify if all went well and we got the proper group
3924   std::vector<RawAddress> devs = LeAudioClient::Get()->GetGroupDevices(group_id);
3925   ASSERT_NE(std::find(devs.begin(), devs.end(), test_address0), devs.end());
3926   ASSERT_NE(std::find(devs.begin(), devs.end(), test_address1), devs.end());
3927 
3928   DisconnectLeAudioWithAclClose(test_address0, 1);
3929   DisconnectLeAudioWithAclClose(test_address1, 2);
3930 }
3931 
TEST_F(UnicastTestNoInit,LoadStoredEarbudsCsisGrouped)3932 TEST_F(UnicastTestNoInit, LoadStoredEarbudsCsisGrouped) {
3933   // Prepare two devices
3934   uint8_t group_size = 2;
3935   uint8_t group_id = 2;
3936 
3937   /* Prepare  mock to not inject connect event so the device can stay in
3938    * CONNECTING state*/
3939   ON_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_DIRECT_CONNECTION, false))
3940           .WillByDefault(DoAll(Return()));
3941 
3942   const RawAddress test_address0 = GetTestAddress(0);
3943   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationFrontLeft,
3944                                 codec_spec_conf::kLeAudioLocationFrontLeft, default_channel_cnt,
3945                                 default_channel_cnt, 0x0004,
3946                                 /* source sample freq 16khz */ true, /*add_csis*/
3947                                 true,                                /*add_cas*/
3948                                 true,                                /*add_pacs*/
3949                                 default_ase_cnt,                     /*add_ascs_cnt*/
3950                                 group_size, 1);
3951 
3952   const RawAddress test_address1 = GetTestAddress(1);
3953   SetSampleDatabaseEarbudsValid(2, test_address1, codec_spec_conf::kLeAudioLocationFrontRight,
3954                                 codec_spec_conf::kLeAudioLocationFrontRight, default_channel_cnt,
3955                                 default_channel_cnt, 0x0004,
3956                                 /* source sample freq 16khz */ true, /*add_csis*/
3957                                 true,                                /*add_cas*/
3958                                 true,                                /*add_pacs*/
3959                                 default_ase_cnt,                     /*add_ascs_cnt*/
3960                                 group_size, 2);
3961 
3962   // Load devices from the storage when storage API is called
3963   bool autoconnect = true;
3964 
3965   /* Common storage values */
3966   std::vector<uint8_t> handles;
3967   LeAudioClient::GetHandlesForStorage(test_address0, handles);
3968 
3969   std::vector<uint8_t> ases;
3970   LeAudioClient::GetAsesForStorage(test_address0, ases);
3971 
3972   std::vector<uint8_t> src_pacs;
3973   LeAudioClient::GetSourcePacsForStorage(test_address0, src_pacs);
3974 
3975   std::vector<uint8_t> snk_pacs;
3976   LeAudioClient::GetSinkPacsForStorage(test_address0, snk_pacs);
3977 
3978   EXPECT_CALL(mock_storage_load, Call()).WillOnce([&]() {
3979     do_in_main_thread(base::BindOnce(&LeAudioClient::AddFromStorage, test_address0, autoconnect,
3980                                      codec_spec_conf::kLeAudioLocationFrontLeft,
3981                                      codec_spec_conf::kLeAudioLocationFrontLeft, 0xff, 0xff,
3982                                      std::move(handles), std::move(snk_pacs), std::move(src_pacs),
3983                                      std::move(ases)));
3984     do_in_main_thread(base::BindOnce(&LeAudioClient::AddFromStorage, test_address1, autoconnect,
3985                                      codec_spec_conf::kLeAudioLocationFrontRight,
3986                                      codec_spec_conf::kLeAudioLocationFrontRight, 0xff, 0xff,
3987                                      std::move(handles), std::move(snk_pacs), std::move(src_pacs),
3988                                      std::move(ases)));
3989     SyncOnMainLoop();
3990   });
3991 
3992   // Expect stored device0 to connect automatically (first directed connection )
3993   EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address0, BTM_BLE_DIRECT_CONNECTION, _))
3994           .Times(1);
3995 
3996   // Expect stored device1 to connect automatically (first direct connection)
3997   EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address1, BTM_BLE_DIRECT_CONNECTION, _))
3998           .Times(1);
3999 
4000   ON_CALL(mock_btm_interface_, BTM_IsEncrypted(test_address1, _))
4001           .WillByDefault(DoAll(Return(true)));
4002   ON_CALL(mock_btm_interface_, BTM_IsEncrypted(test_address0, _))
4003           .WillByDefault(DoAll(Return(true)));
4004 
4005   ON_CALL(mock_groups_module_, GetGroupId(_, _)).WillByDefault(DoAll(Return(group_id)));
4006 
4007   ON_CALL(mock_btm_interface_, GetSecurityFlagsByTransport(test_address0, NotNull(), _))
4008           .WillByDefault(DoAll(SetArgPointee<1>(BTM_SEC_FLAG_ENCRYPTED), Return(true)));
4009 
4010   std::vector<::bluetooth::le_audio::btle_audio_codec_config_t> framework_encode_preference;
4011 
4012   // Initialize
4013   BtaAppRegisterCallback app_register_callback;
4014   ON_CALL(mock_gatt_interface_, AppRegister(_, _, _))
4015           .WillByDefault(DoAll(SaveArg<0>(&gatt_callback), SaveArg<1>(&app_register_callback)));
4016   LeAudioClient::Initialize(
4017           &mock_audio_hal_client_callbacks_,
4018           base::Bind([](MockFunction<void()>* foo) { foo->Call(); }, &mock_storage_load),
4019           base::Bind([](MockFunction<bool()>* foo) { return foo->Call(); }, &mock_hal_2_1_verifier),
4020           framework_encode_preference);
4021   if (app_register_callback) {
4022     app_register_callback.Run(gatt_if, GATT_SUCCESS);
4023   }
4024 
4025   // We need to wait for the storage callback before verifying stuff
4026   SyncOnMainLoop();
4027   ASSERT_TRUE(LeAudioClient::IsLeAudioClientRunning());
4028   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
4029 
4030   // Simulate devices are not there and phone fallbacks to targeted
4031   // announcements
4032   EXPECT_CALL(mock_gatt_interface_,
4033               Open(gatt_if, test_address0, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _))
4034           .Times(1);
4035 
4036   EXPECT_CALL(mock_gatt_interface_,
4037               Open(gatt_if, test_address1, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _))
4038           .Times(1);
4039 
4040   // Devices not found
4041   InjectConnectedEvent(test_address0, 0, GATT_ERROR);
4042   InjectConnectedEvent(test_address1, 0, GATT_ERROR);
4043 
4044   SyncOnMainLoop();
4045   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
4046 
4047   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4048               OnConnectionState(ConnectionState::CONNECTED, test_address0))
4049           .Times(1);
4050 
4051   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4052               OnConnectionState(ConnectionState::CONNECTED, test_address1))
4053           .Times(1);
4054 
4055   /* For background connect, test needs to Inject Connected Event */
4056   InjectConnectedEvent(test_address0, 1);
4057   InjectConnectedEvent(test_address1, 2);
4058   SyncOnMainLoop();
4059 
4060   // Verify if all went well and we got the proper group
4061   std::vector<RawAddress> devs = LeAudioClient::Get()->GetGroupDevices(group_id);
4062   ASSERT_NE(std::find(devs.begin(), devs.end(), test_address0), devs.end());
4063   ASSERT_NE(std::find(devs.begin(), devs.end(), test_address1), devs.end());
4064 
4065   DisconnectLeAudioWithAclClose(test_address0, 1);
4066   DisconnectLeAudioWithAclClose(test_address1, 2);
4067 }
4068 
TEST_F(UnicastTest,LoadStoredBandedHeadphones)4069 TEST_F(UnicastTest, LoadStoredBandedHeadphones) {
4070   const RawAddress test_address0 = GetTestAddress(0);
4071   uint16_t conn_id = 1;
4072 
4073   SetSampleDatabaseEarbudsValid(
4074           conn_id, test_address0,
4075           codec_spec_conf::kLeAudioLocationFrontLeft | codec_spec_conf::kLeAudioLocationFrontRight,
4076           codec_spec_conf::kLeAudioLocationMonoAudio, 2, 1, 0x0004,
4077           /* source sample freq 16khz */ false, /*add_csis*/
4078           true,                                 /*add_cas*/
4079           true,                                 /*add_pacs*/
4080           true,                                 /*add_ascs*/
4081           0, 0);
4082   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4083               OnConnectionState(ConnectionState::CONNECTED, test_address0))
4084           .Times(1);
4085 
4086   /* Connect and fill the device storage */
4087   ConnectLeAudio(test_address0);
4088 
4089   std::vector<uint8_t> handles;
4090   LeAudioClient::GetHandlesForStorage(test_address0, handles);
4091 
4092   std::vector<uint8_t> ases;
4093   LeAudioClient::GetAsesForStorage(test_address0, ases);
4094 
4095   std::vector<uint8_t> src_pacs;
4096   LeAudioClient::GetSourcePacsForStorage(test_address0, src_pacs);
4097 
4098   std::vector<uint8_t> snk_pacs;
4099   LeAudioClient::GetSinkPacsForStorage(test_address0, snk_pacs);
4100 
4101   /* Disconnect & Cleanup */
4102   DisconnectLeAudioWithAclClose(test_address0, conn_id);
4103   if (LeAudioClient::IsLeAudioClientRunning()) {
4104     LeAudioClient::Cleanup();
4105     ASSERT_FALSE(LeAudioClient::IsLeAudioClientRunning());
4106   }
4107 
4108   Mock::VerifyAndClearExpectations(&mock_hal_2_1_verifier);
4109   Mock::VerifyAndClearExpectations(&mock_storage_load);
4110 
4111   // Load devices from the storage when storage API is called
4112   bool autoconnect = true;
4113   EXPECT_CALL(mock_storage_load, Call()).WillOnce([&]() {
4114     do_in_main_thread(base::BindOnce(&LeAudioClient::AddFromStorage, test_address0, autoconnect,
4115                                      codec_spec_conf::kLeAudioLocationFrontLeft |
4116                                              codec_spec_conf::kLeAudioLocationFrontRight,
4117                                      codec_spec_conf::kLeAudioLocationMonoAudio, 0xff, 0xff,
4118                                      std::move(handles), std::move(snk_pacs), std::move(src_pacs),
4119                                      std::move(ases)));
4120     SyncOnMainLoop();
4121   });
4122 
4123   /* Prepare  mock to not inject connect event so the device can stay in
4124    * CONNECTING state*/
4125   ON_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_DIRECT_CONNECTION, false))
4126           .WillByDefault(DoAll(Return()));
4127 
4128   // Re-Initialize & load from storage
4129   BtaAppRegisterCallback app_register_callback;
4130   ON_CALL(mock_gatt_interface_, AppRegister(_, _, _))
4131           .WillByDefault(DoAll(SaveArg<0>(&gatt_callback), SaveArg<1>(&app_register_callback)));
4132   std::vector<::bluetooth::le_audio::btle_audio_codec_config_t> framework_encode_preference;
4133   LeAudioClient::Initialize(
4134           &mock_audio_hal_client_callbacks_,
4135           base::Bind([](MockFunction<void()>* foo) { foo->Call(); }, &mock_storage_load),
4136           base::Bind([](MockFunction<bool()>* foo) { return foo->Call(); }, &mock_hal_2_1_verifier),
4137           framework_encode_preference);
4138   if (app_register_callback) {
4139     app_register_callback.Run(gatt_if, GATT_SUCCESS);
4140   }
4141 
4142   InjectConnectedEvent(test_address0, conn_id);
4143   SyncOnMainLoop();
4144   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
4145 
4146   // Verify if all went well and we got the proper group
4147   auto group_id = MockDeviceGroups::DeviceGroups::Get()->GetGroupId(test_address0);
4148   std::vector<RawAddress> devs = LeAudioClient::Get()->GetGroupDevices(group_id);
4149   ASSERT_NE(std::find(devs.begin(), devs.end(), test_address0), devs.end());
4150 
4151   SetUpMockCodecManager(::bluetooth::le_audio::types::CodecLocation::HOST);
4152 
4153   // Start streaming
4154   LeAudioClient::Get()->GroupSetActive(group_id);
4155   SyncOnMainLoop();
4156 
4157   EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, _)).Times(1);
4158   EXPECT_CALL(mock_audio_hal_client_callbacks_, OnAudioGroupCurrentCodecConf(group_id, _, _))
4159           .Times(1);
4160   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
4161 
4162   SyncOnMainLoop();
4163   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
4164   Mock::VerifyAndClearExpectations(&mock_state_machine_);
4165 
4166   ASSERT_NE(0lu, streaming_groups.count(group_id));
4167   auto group = streaming_groups.at(group_id);
4168   ASSERT_NE(group, nullptr);
4169 
4170   auto device = group->GetFirstDevice();
4171   ASSERT_NE(device, nullptr);
4172   ASSERT_EQ(device->audio_directions_, bluetooth::le_audio::types::kLeAudioDirectionSink |
4173                                                bluetooth::le_audio::types::kLeAudioDirectionSource);
4174 
4175   DisconnectLeAudioWithAclClose(test_address0, conn_id);
4176 }
4177 
TEST_F(UnicastTestNoInit,ServiceChangedBeforeServiceIsConnected)4178 TEST_F(UnicastTestNoInit, ServiceChangedBeforeServiceIsConnected) {
4179   // Prepare two devices
4180   uint8_t group_size = 2;
4181   uint8_t group_id = 2;
4182 
4183   /* Prepare  mock to not inject connect event so the device can stay in
4184    * CONNECTING state*/
4185   ON_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_DIRECT_CONNECTION, false))
4186           .WillByDefault(DoAll(Return()));
4187 
4188   const RawAddress test_address0 = GetTestAddress(0);
4189   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationFrontLeft,
4190                                 codec_spec_conf::kLeAudioLocationFrontLeft, default_channel_cnt,
4191                                 default_channel_cnt, 0x0004,
4192                                 /* source sample freq 16khz */ true, /*add_csis*/
4193                                 true,                                /*add_cas*/
4194                                 true,                                /*add_pacs*/
4195                                 default_ase_cnt,                     /*add_ascs_cnt*/
4196                                 group_size, 1);
4197 
4198   const RawAddress test_address1 = GetTestAddress(1);
4199   SetSampleDatabaseEarbudsValid(2, test_address1, codec_spec_conf::kLeAudioLocationFrontRight,
4200                                 codec_spec_conf::kLeAudioLocationFrontRight, default_channel_cnt,
4201                                 default_channel_cnt, 0x0004,
4202                                 /* source sample freq 16khz */ true, /*add_csis*/
4203                                 true,                                /*add_cas*/
4204                                 true,                                /*add_pacs*/
4205                                 default_ase_cnt,                     /*add_ascs_cnt*/
4206                                 group_size, 2);
4207 
4208   // Load devices from the storage when storage API is called
4209   bool autoconnect = true;
4210 
4211   /* Common storage values */
4212   std::vector<uint8_t> handles;
4213   LeAudioClient::GetHandlesForStorage(test_address0, handles);
4214 
4215   std::vector<uint8_t> ases;
4216   LeAudioClient::GetAsesForStorage(test_address0, ases);
4217 
4218   std::vector<uint8_t> src_pacs;
4219   LeAudioClient::GetSourcePacsForStorage(test_address0, src_pacs);
4220 
4221   std::vector<uint8_t> snk_pacs;
4222   LeAudioClient::GetSinkPacsForStorage(test_address0, snk_pacs);
4223 
4224   EXPECT_CALL(mock_storage_load, Call()).WillOnce([&]() {
4225     do_in_main_thread(base::BindOnce(&LeAudioClient::AddFromStorage, test_address0, autoconnect,
4226                                      codec_spec_conf::kLeAudioLocationFrontLeft,
4227                                      codec_spec_conf::kLeAudioLocationFrontLeft, 0xff, 0xff,
4228                                      std::move(handles), std::move(snk_pacs), std::move(src_pacs),
4229                                      std::move(ases)));
4230     do_in_main_thread(base::BindOnce(&LeAudioClient::AddFromStorage, test_address1, autoconnect,
4231                                      codec_spec_conf::kLeAudioLocationFrontRight,
4232                                      codec_spec_conf::kLeAudioLocationFrontRight, 0xff, 0xff,
4233                                      std::move(handles), std::move(snk_pacs), std::move(src_pacs),
4234                                      std::move(ases)));
4235     SyncOnMainLoop();
4236   });
4237 
4238   // Expect stored device0 to connect automatically (first directed connection )
4239   EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address0, BTM_BLE_DIRECT_CONNECTION, _))
4240           .Times(1);
4241 
4242   // Expect stored device1 to connect automatically (first direct connection)
4243   EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address1, BTM_BLE_DIRECT_CONNECTION, _))
4244           .Times(1);
4245 
4246   ON_CALL(mock_btm_interface_, BTM_IsEncrypted(test_address1, _))
4247           .WillByDefault(DoAll(Return(true)));
4248   ON_CALL(mock_btm_interface_, BTM_IsEncrypted(test_address0, _))
4249           .WillByDefault(DoAll(Return(true)));
4250 
4251   ON_CALL(mock_groups_module_, GetGroupId(_, _)).WillByDefault(DoAll(Return(group_id)));
4252 
4253   ON_CALL(mock_btm_interface_, GetSecurityFlagsByTransport(test_address0, NotNull(), _))
4254           .WillByDefault(DoAll(SetArgPointee<1>(BTM_SEC_FLAG_ENCRYPTED), Return(true)));
4255 
4256   std::vector<::bluetooth::le_audio::btle_audio_codec_config_t> framework_encode_preference;
4257 
4258   // Initialize
4259   BtaAppRegisterCallback app_register_callback;
4260   ON_CALL(mock_gatt_interface_, AppRegister(_, _, _))
4261           .WillByDefault(DoAll(SaveArg<0>(&gatt_callback), SaveArg<1>(&app_register_callback)));
4262   LeAudioClient::Initialize(
4263           &mock_audio_hal_client_callbacks_,
4264           base::Bind([](MockFunction<void()>* foo) { foo->Call(); }, &mock_storage_load),
4265           base::Bind([](MockFunction<bool()>* foo) { return foo->Call(); }, &mock_hal_2_1_verifier),
4266           framework_encode_preference);
4267   if (app_register_callback) {
4268     app_register_callback.Run(gatt_if, GATT_SUCCESS);
4269   }
4270 
4271   // We need to wait for the storage callback before verifying stuff
4272   SyncOnMainLoop();
4273   ASSERT_TRUE(LeAudioClient::IsLeAudioClientRunning());
4274   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
4275 
4276   /* Inject Service Changed */
4277   InjectServiceChangedEvent(test_address1, 0xffff);
4278   SyncOnMainLoop();
4279   InjectServiceChangedEvent(test_address0, 0xffff);
4280   SyncOnMainLoop();
4281   /* Stack should rediscover services as storage is broken */
4282   EXPECT_CALL(mock_gatt_interface_, ServiceSearchRequest(2, _)).Times(1);
4283   EXPECT_CALL(mock_gatt_interface_, ServiceSearchRequest(1, _)).Times(1);
4284 
4285   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4286               OnConnectionState(ConnectionState::CONNECTED, test_address0))
4287           .Times(1);
4288 
4289   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4290               OnConnectionState(ConnectionState::CONNECTED, test_address1))
4291           .Times(1);
4292 
4293   /* For background connect, test needs to Inject Connected Event */
4294   InjectConnectedEvent(test_address0, 1);
4295   InjectConnectedEvent(test_address1, 2);
4296   SyncOnMainLoop();
4297 
4298   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
4299   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
4300 }
4301 
TEST_F(UnicastTestNoInit,LoadStoredEarbudsCsisGroupedDifferently)4302 TEST_F(UnicastTestNoInit, LoadStoredEarbudsCsisGroupedDifferently) {
4303   // Prepare two devices
4304   uint8_t group_size = 1;
4305 
4306   // Device 0
4307   uint8_t group_id0 = 2;
4308   bool autoconnect0 = true;
4309   const RawAddress test_address0 = GetTestAddress(0);
4310   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationFrontLeft,
4311                                 codec_spec_conf::kLeAudioLocationFrontLeft, 0x0004,
4312                                 /* source sample freq 16khz */ true, /*add_csis*/
4313                                 true,                                /*add_cas*/
4314                                 true,                                /*add_pacs*/
4315                                 true,                                /*add_ascs*/
4316                                 group_size, 1);
4317 
4318   ON_CALL(mock_groups_module_, GetGroupId(test_address0, _))
4319           .WillByDefault(DoAll(Return(group_id0)));
4320 
4321   // Device 1
4322   uint8_t group_id1 = 3;
4323   bool autoconnect1 = false;
4324   const RawAddress test_address1 = GetTestAddress(1);
4325   SetSampleDatabaseEarbudsValid(2, test_address1, codec_spec_conf::kLeAudioLocationFrontRight,
4326                                 codec_spec_conf::kLeAudioLocationFrontRight, default_channel_cnt,
4327                                 default_channel_cnt, 0x0004,
4328                                 /* source sample freq 16khz */ true, /*add_csis*/
4329                                 true,                                /*add_cas*/
4330                                 true,                                /*add_pacs*/
4331                                 default_ase_cnt,                     /*add_ascs_cnt*/
4332                                 group_size, 2);
4333 
4334   ON_CALL(mock_groups_module_, GetGroupId(test_address1, _))
4335           .WillByDefault(DoAll(Return(group_id1)));
4336 
4337   /* Commont storage values */
4338   std::vector<uint8_t> handles;
4339   LeAudioClient::GetHandlesForStorage(test_address0, handles);
4340 
4341   std::vector<uint8_t> ases;
4342   LeAudioClient::GetAsesForStorage(test_address0, ases);
4343 
4344   std::vector<uint8_t> src_pacs;
4345   LeAudioClient::GetSourcePacsForStorage(test_address0, src_pacs);
4346 
4347   std::vector<uint8_t> snk_pacs;
4348   LeAudioClient::GetSinkPacsForStorage(test_address0, snk_pacs);
4349 
4350   // Load devices from the storage when storage API is called
4351   EXPECT_CALL(mock_storage_load, Call()).WillOnce([&]() {
4352     do_in_main_thread(base::BindOnce(&LeAudioClient::AddFromStorage, test_address0, autoconnect0,
4353                                      codec_spec_conf::kLeAudioLocationFrontLeft,
4354                                      codec_spec_conf::kLeAudioLocationFrontLeft, 0xff, 0xff,
4355                                      std::move(handles), std::move(snk_pacs), std::move(src_pacs),
4356                                      std::move(ases)));
4357     do_in_main_thread(base::BindOnce(&LeAudioClient::AddFromStorage, test_address1, autoconnect1,
4358                                      codec_spec_conf::kLeAudioLocationFrontRight,
4359                                      codec_spec_conf::kLeAudioLocationFrontRight, 0xff, 0xff,
4360                                      std::move(handles), std::move(snk_pacs), std::move(src_pacs),
4361                                      std::move(ases)));
4362   });
4363 
4364   // Expect stored device0 to connect automatically
4365   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4366               OnConnectionState(ConnectionState::CONNECTED, test_address0))
4367           .Times(1);
4368   ON_CALL(mock_btm_interface_, BTM_IsEncrypted(test_address0, _))
4369           .WillByDefault(DoAll(Return(true)));
4370 
4371   // First device will got connected
4372   EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address0, BTM_BLE_DIRECT_CONNECTION, _))
4373           .Times(1);
4374   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, _)).Times(1);
4375   EXPECT_CALL(mock_gatt_interface_,
4376               Open(gatt_if, test_address0, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _))
4377           .Times(1);
4378 
4379   // Expect stored device1 to NOT connect automatically
4380   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4381               OnConnectionState(ConnectionState::CONNECTED, test_address1))
4382           .Times(0);
4383   ON_CALL(mock_btm_interface_, BTM_IsEncrypted(test_address1, _))
4384           .WillByDefault(DoAll(Return(true)));
4385 
4386   EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address1, BTM_BLE_DIRECT_CONNECTION, _))
4387           .Times(0);
4388 
4389   // Initialize
4390   BtaAppRegisterCallback app_register_callback;
4391   ON_CALL(mock_gatt_interface_, AppRegister(_, _, _))
4392           .WillByDefault(DoAll(SaveArg<0>(&gatt_callback), SaveArg<1>(&app_register_callback)));
4393   std::vector<::bluetooth::le_audio::btle_audio_codec_config_t> framework_encode_preference;
4394   LeAudioClient::Initialize(
4395           &mock_audio_hal_client_callbacks_,
4396           base::Bind([](MockFunction<void()>* foo) { foo->Call(); }, &mock_storage_load),
4397           base::Bind([](MockFunction<bool()>* foo) { return foo->Call(); }, &mock_hal_2_1_verifier),
4398           framework_encode_preference);
4399   if (app_register_callback) {
4400     app_register_callback.Run(gatt_if, GATT_SUCCESS);
4401   }
4402 
4403   // We need to wait for the storage callback before verifying stuff
4404   SyncOnMainLoop();
4405   ASSERT_TRUE(LeAudioClient::IsLeAudioClientRunning());
4406   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
4407   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
4408 
4409   // Simulate device is not there and phone fallbacks to targeted announcements
4410   EXPECT_CALL(mock_gatt_interface_,
4411               Open(gatt_if, test_address0, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _))
4412           .Times(1);
4413 
4414   // Devices 0 is connected. Disconnect it
4415   InjectDisconnectedEvent(1, GATT_CONN_TERMINATE_PEER_USER);
4416 
4417   SyncOnMainLoop();
4418   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
4419 
4420   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, _)).Times(1);
4421   EXPECT_CALL(mock_gatt_interface_,
4422               Open(gatt_if, test_address0, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _))
4423           .Times(1);
4424 
4425   /* Keep device in Getting Ready state */
4426   ON_CALL(mock_btm_interface_, BTM_IsEncrypted(test_address0, _))
4427           .WillByDefault(DoAll(Return(false)));
4428   ON_CALL(mock_btm_interface_, SetEncryption(test_address0, _, _, _, _))
4429           .WillByDefault(Return(tBTM_STATUS::BTM_SUCCESS));
4430 
4431   /* For background connect, test needs to Inject Connected Event */
4432   InjectConnectedEvent(test_address0, 1);
4433 
4434   // We need to wait for the storage callback before verifying stuff
4435   SyncOnMainLoop();
4436   ASSERT_TRUE(LeAudioClient::IsLeAudioClientRunning());
4437   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
4438 
4439   std::vector<RawAddress> devs = LeAudioClient::Get()->GetGroupDevices(group_id0);
4440   ASSERT_NE(std::find(devs.begin(), devs.end(), test_address0), devs.end());
4441   ASSERT_EQ(std::find(devs.begin(), devs.end(), test_address1), devs.end());
4442 
4443   devs = LeAudioClient::Get()->GetGroupDevices(group_id1);
4444   ASSERT_EQ(std::find(devs.begin(), devs.end(), test_address0), devs.end());
4445   ASSERT_NE(std::find(devs.begin(), devs.end(), test_address1), devs.end());
4446 
4447   /* Disconnects while being in getting ready state */
4448   DisconnectLeAudioWithGattClose(test_address0, 1);
4449 }
4450 
TEST_F(UnicastTest,GroupingAddRemove)4451 TEST_F(UnicastTest, GroupingAddRemove) {
4452   // Earbud connects without known grouping
4453   uint8_t group_id0 = bluetooth::groups::kGroupUnknown;
4454   const RawAddress test_address0 = GetTestAddress(0);
4455 
4456   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
4457   ConnectNonCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
4458                        codec_spec_conf::kLeAudioLocationFrontLeft);
4459 
4460   group_id0 = MockDeviceGroups::DeviceGroups::Get()->GetGroupId(test_address0);
4461 
4462   // Earbud connects without known grouping
4463   uint8_t group_id1 = bluetooth::groups::kGroupUnknown;
4464   const RawAddress test_address1 = GetTestAddress(1);
4465   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
4466   ConnectNonCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
4467                        codec_spec_conf::kLeAudioLocationFrontRight);
4468 
4469   group_id1 = MockDeviceGroups::DeviceGroups::Get()->GetGroupId(test_address1);
4470 
4471   Mock::VerifyAndClearExpectations(&mock_btif_storage_);
4472 
4473   // Verify individual groups
4474   ASSERT_NE(group_id0, bluetooth::groups::kGroupUnknown);
4475   ASSERT_NE(group_id1, bluetooth::groups::kGroupUnknown);
4476   ASSERT_NE(group_id0, group_id1);
4477   ASSERT_EQ(LeAudioClient::Get()->GetGroupDevices(group_id0).size(), 1u);
4478   ASSERT_EQ(LeAudioClient::Get()->GetGroupDevices(group_id1).size(), 1u);
4479 
4480   // Expectations on reassigning second earbud to the first group
4481   int dev1_storage_group = bluetooth::groups::kGroupUnknown;
4482   int dev1_new_group = bluetooth::groups::kGroupUnknown;
4483 
4484   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4485               OnGroupNodeStatus(test_address1, group_id1, GroupNodeStatus::REMOVED))
4486           .Times(AtLeast(1));
4487   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4488               OnGroupNodeStatus(test_address1, _, GroupNodeStatus::ADDED))
4489           .WillRepeatedly(SaveArg<1>(&dev1_new_group));
4490   EXPECT_CALL(mock_groups_module_, RemoveDevice(test_address1, group_id1)).Times(AtLeast(1));
4491   EXPECT_CALL(mock_groups_module_, AddDevice(test_address1, _, _)).Times(AnyNumber());
4492 
4493   LeAudioClient::Get()->GroupRemoveNode(group_id1, test_address1);
4494   SyncOnMainLoop();
4495 
4496   Mock::VerifyAndClearExpectations(&mock_groups_module_);
4497   Mock::VerifyAndClearExpectations(&mock_btif_storage_);
4498 
4499   EXPECT_CALL(mock_groups_module_, AddDevice(test_address1, _, group_id0)).Times(1);
4500 
4501   LeAudioClient::Get()->GroupAddNode(group_id0, test_address1);
4502   SyncOnMainLoop();
4503   Mock::VerifyAndClearExpectations(&mock_groups_module_);
4504 
4505   dev1_storage_group = MockDeviceGroups::DeviceGroups::Get()->GetGroupId(test_address1);
4506 
4507   // Verify regrouping results
4508   EXPECT_EQ(dev1_new_group, group_id0);
4509   EXPECT_EQ(dev1_new_group, dev1_storage_group);
4510   ASSERT_EQ(LeAudioClient::Get()->GetGroupDevices(group_id1).size(), 0u);
4511   ASSERT_EQ(LeAudioClient::Get()->GetGroupDevices(group_id0).size(), 2u);
4512   std::vector<RawAddress> devs = LeAudioClient::Get()->GetGroupDevices(group_id0);
4513   ASSERT_NE(std::find(devs.begin(), devs.end(), test_address0), devs.end());
4514   ASSERT_NE(std::find(devs.begin(), devs.end(), test_address1), devs.end());
4515 }
4516 
TEST_F(UnicastTest,DoubleResumeFromAF)4517 TEST_F(UnicastTest, DoubleResumeFromAF) {
4518   const RawAddress test_address0 = GetTestAddress(0);
4519   int group_id = bluetooth::groups::kGroupUnknown;
4520 
4521   SetSampleDatabaseEarbudsValid(
4522           1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
4523           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
4524           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
4525           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
4526   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4527               OnConnectionState(ConnectionState::CONNECTED, test_address0))
4528           .Times(1);
4529   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4530               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
4531           .WillOnce(DoAll(SaveArg<1>(&group_id)));
4532 
4533   ConnectLeAudio(test_address0);
4534   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
4535 
4536   constexpr int gmcs_ccid = 1;
4537   constexpr int gtbs_ccid = 2;
4538 
4539   // Audio sessions are started only when device gets active
4540   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
4541   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
4542   LeAudioClient::Get()->SetCcidInformation(gmcs_ccid, 4 /* Media */);
4543   LeAudioClient::Get()->SetCcidInformation(gtbs_ccid, 2 /* Phone */);
4544   LeAudioClient::Get()->GroupSetActive(group_id);
4545   SyncOnMainLoop();
4546 
4547   types::BidirectionalPair<std::vector<uint8_t>> ccids = {.sink = {gmcs_ccid}, .source = {}};
4548   EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, ccids)).Times(1);
4549 
4550   stay_at_qos_config_in_start_stream = true;
4551 
4552   UpdateLocalSourceMetadata(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC);
4553   LocalAudioSourceResume(false);
4554 
4555   SyncOnMainLoop();
4556   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
4557   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
4558 
4559   // Additional resume shall be ignored.
4560   LocalAudioSourceResume(false, false);
4561 
4562   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(0);
4563 
4564   do_in_main_thread(base::BindOnce(
4565           [](int group_id,
4566              bluetooth::le_audio::LeAudioGroupStateMachine::Callbacks* state_machine_callbacks) {
4567             state_machine_callbacks->StatusReportCb(group_id, GroupStreamStatus::STREAMING);
4568           },
4569           group_id, base::Unretained(state_machine_callbacks_)));
4570   SyncOnMainLoop();
4571   Mock::VerifyAndClearExpectations(&mock_state_machine_);
4572 
4573   // Verify Data transfer on one audio source cis
4574   constexpr uint8_t cis_count_out = 1;
4575   constexpr uint8_t cis_count_in = 0;
4576   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
4577 }
4578 
TEST_F(UnicastTest,DoubleResumeFromAFOnLocalSink)4579 TEST_F(UnicastTest, DoubleResumeFromAFOnLocalSink) {
4580   const RawAddress test_address0 = GetTestAddress(0);
4581   int group_id = bluetooth::groups::kGroupUnknown;
4582 
4583   default_channel_cnt = 1;
4584 
4585   SetSampleDatabaseEarbudsValid(
4586           1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
4587           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
4588           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
4589           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
4590   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4591               OnConnectionState(ConnectionState::CONNECTED, test_address0))
4592           .Times(1);
4593   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4594               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
4595           .WillOnce(DoAll(SaveArg<1>(&group_id)));
4596 
4597   ConnectLeAudio(test_address0);
4598   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
4599 
4600   // Audio sessions are started only when device gets active
4601   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
4602   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
4603   LeAudioClient::Get()->GroupSetActive(group_id);
4604   SyncOnMainLoop();
4605 
4606   EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, _)).Times(1);
4607 
4608   stay_at_qos_config_in_start_stream = true;
4609 
4610   UpdateLocalSinkMetadata(AUDIO_SOURCE_MIC);
4611   LocalAudioSinkResume();
4612 
4613   SyncOnMainLoop();
4614   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
4615   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
4616 
4617   EXPECT_CALL(*mock_le_audio_sink_hal_client_, CancelStreamingRequest()).Times(0);
4618 
4619   // Actuall test here: send additional resume which shall be ignored.
4620   LocalAudioSinkResume();
4621 
4622   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(0);
4623 
4624   do_in_main_thread(base::BindOnce(
4625           [](int group_id,
4626              bluetooth::le_audio::LeAudioGroupStateMachine::Callbacks* state_machine_callbacks) {
4627             state_machine_callbacks->StatusReportCb(group_id, GroupStreamStatus::STREAMING);
4628           },
4629           group_id, base::Unretained(state_machine_callbacks_)));
4630   SyncOnMainLoop();
4631   Mock::VerifyAndClearExpectations(&mock_state_machine_);
4632 
4633   // Verify Data transfer on local audio sink which is started
4634   constexpr uint8_t cis_count_out = 0;
4635   constexpr uint8_t cis_count_in = 1;
4636   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 0, 40);
4637 }
4638 
TEST_F(UnicastTest,HandleResumeWithoutMetadataUpdateOnLocalSink)4639 TEST_F(UnicastTest, HandleResumeWithoutMetadataUpdateOnLocalSink) {
4640   const RawAddress test_address0 = GetTestAddress(0);
4641   int group_id = bluetooth::groups::kGroupUnknown;
4642 
4643   /**
4644    * In this test we want to make sure that if MetadataUpdate is
4645    * not called before Resume, but the context type is supported,
4646    * stream should be created
4647    */
4648 
4649   default_channel_cnt = 1;
4650 
4651   SetSampleDatabaseEarbudsValid(
4652           1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
4653           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
4654           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
4655           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
4656   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4657               OnConnectionState(ConnectionState::CONNECTED, test_address0))
4658           .Times(1);
4659   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4660               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
4661           .WillOnce(DoAll(SaveArg<1>(&group_id)));
4662 
4663   ConnectLeAudio(test_address0);
4664   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
4665 
4666   // Audio sessions are started only when device gets active
4667   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
4668   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
4669   LeAudioClient::Get()->GroupSetActive(group_id);
4670   SyncOnMainLoop();
4671 
4672   EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, _)).Times(1);
4673 
4674   UpdateLocalSinkMetadata(AUDIO_SOURCE_MIC);
4675   LocalAudioSinkResume();
4676 
4677   SyncOnMainLoop();
4678   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
4679   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
4680   Mock::VerifyAndClearExpectations(&mock_state_machine_);
4681 
4682   // Verify Data transfer on local audio sink which is started
4683   constexpr uint8_t cis_count_out = 0;
4684   constexpr uint8_t cis_count_in = 1;
4685   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 0, 40);
4686 
4687   SyncOnMainLoop();
4688   /* Clear cache by changing context types, this is required for the test
4689    * as setting active device actually generate cache
4690    */
4691   auto sink_available_context = types::kLeAudioContextAllRemoteSinkOnly;
4692   auto source_available_context = types::kLeAudioContextAllRemoteSource;
4693   InjectAvailableContextTypes(test_address0, 1, sink_available_context, source_available_context);
4694 
4695   StopStreaming(group_id, true);
4696   SyncOnMainLoop();
4697 
4698   // simulate suspend timeout passed, alarm executing
4699   fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
4700   SyncOnMainLoop();
4701 
4702   EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, _)).Times(1);
4703 
4704   // Resume without metadata update while cached configuration is cleared
4705   LocalAudioSinkResume();
4706   SyncOnMainLoop();
4707   Mock::VerifyAndClearExpectations(&mock_state_machine_);
4708 }
4709 
TEST_F(UnicastTest,GroupSetActiveNonConnectedGroup)4710 TEST_F(UnicastTest, GroupSetActiveNonConnectedGroup) {
4711   const RawAddress test_address0 = GetTestAddress(0);
4712   int group_id = bluetooth::groups::kGroupUnknown;
4713 
4714   /**
4715    * In this test we want to make sure that Available context change reach Java
4716    * when group is in Configured state
4717    */
4718 
4719   default_channel_cnt = 1;
4720   int conn_id = 1;
4721   SetSampleDatabaseEarbudsValid(
4722           conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo,
4723           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
4724           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
4725           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
4726   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4727               OnConnectionState(ConnectionState::CONNECTED, test_address0))
4728           .Times(1);
4729   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4730               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
4731           .WillOnce(DoAll(SaveArg<1>(&group_id)));
4732 
4733   ConnectLeAudio(test_address0);
4734   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
4735 
4736   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
4737 
4738   EXPECT_CALL(mock_audio_hal_client_callbacks_, OnGroupStatus(group_id, GroupStatus::INACTIVE))
4739           .Times(1);
4740 
4741   InjectDisconnectedEvent(conn_id);
4742   SyncOnMainLoop();
4743 
4744   // Audio sessions are started only when device gets active
4745   EXPECT_CALL(mock_audio_hal_client_callbacks_, OnAudioGroupSelectableCodecConf(group_id, _, _))
4746           .Times(0);
4747   EXPECT_CALL(mock_audio_hal_client_callbacks_, OnAudioGroupCurrentCodecConf(group_id, _, _))
4748           .Times(0);
4749   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(0);
4750   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(0);
4751 
4752   // try to set active group on non connected group
4753 
4754   LeAudioClient::Get()->GroupSetActive(group_id);
4755   SyncOnMainLoop();
4756   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
4757   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
4758 }
4759 
TEST_F(UnicastTest,GroupSetActive_CurrentCodecSentOfActive)4760 TEST_F(UnicastTest, GroupSetActive_CurrentCodecSentOfActive) {
4761   com::android::bluetooth::flags::provider_->leaudio_codec_config_callback_order_fix(true);
4762   const RawAddress test_address0 = GetTestAddress(0);
4763   int group_id = bluetooth::groups::kGroupUnknown;
4764 
4765   /**
4766    * In this test we want to make sure that Available context change reach Java
4767    * when group is in Configured state
4768    */
4769 
4770   default_channel_cnt = 1;
4771 
4772   SetSampleDatabaseEarbudsValid(
4773           1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
4774           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
4775           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
4776           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
4777   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4778               OnConnectionState(ConnectionState::CONNECTED, test_address0))
4779           .Times(1);
4780   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4781               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
4782           .WillOnce(DoAll(SaveArg<1>(&group_id)));
4783 
4784   ConnectLeAudio(test_address0);
4785   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
4786 
4787   // Audio sessions are started only when device gets active
4788   EXPECT_CALL(mock_audio_hal_client_callbacks_, OnAudioGroupSelectableCodecConf(group_id, _, _))
4789           .Times(1);
4790   btle_audio_codec_config_t empty_conf{};
4791   btle_audio_codec_config_t output_config = {
4792           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
4793           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_48000HZ,
4794           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
4795           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
4796           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
4797           .octets_per_frame = 120};
4798 
4799   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4800               OnAudioGroupCurrentCodecConf(group_id, empty_conf, output_config))
4801           .Times(1);
4802 
4803   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
4804   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
4805   LeAudioClient::Get()->GroupSetActive(group_id);
4806   SyncOnMainLoop();
4807   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
4808   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
4809 }
4810 
TEST_F(UnicastTest,GroupSetActive)4811 TEST_F(UnicastTest, GroupSetActive) {
4812   const RawAddress test_address0 = GetTestAddress(0);
4813   int group_id = bluetooth::groups::kGroupUnknown;
4814 
4815   /**
4816    * In this test we want to make sure that Available context change reach Java
4817    * when group is in Configured state
4818    */
4819 
4820   default_channel_cnt = 1;
4821 
4822   SetSampleDatabaseEarbudsValid(
4823           1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
4824           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
4825           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
4826           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
4827   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4828               OnConnectionState(ConnectionState::CONNECTED, test_address0))
4829           .Times(1);
4830   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4831               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
4832           .WillOnce(DoAll(SaveArg<1>(&group_id)));
4833 
4834   ConnectLeAudio(test_address0);
4835   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
4836 
4837   // Audio sessions are started only when device gets active
4838   EXPECT_CALL(mock_audio_hal_client_callbacks_, OnAudioGroupSelectableCodecConf(group_id, _, _))
4839           .Times(1);
4840   EXPECT_CALL(mock_audio_hal_client_callbacks_, OnGroupStatus(group_id, GroupStatus::ACTIVE))
4841           .Times(1);
4842   EXPECT_CALL(mock_audio_hal_client_callbacks_, OnGroupStatus(_, GroupStatus::INACTIVE)).Times(0);
4843   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
4844   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
4845 
4846   EXPECT_CALL(*mock_codec_manager_,
4847               UpdateActiveUnicastAudioHalClient(mock_le_audio_source_hal_client_,
4848                                                 mock_le_audio_sink_hal_client_, true))
4849           .Times(1);
4850 
4851   LeAudioClient::Get()->GroupSetActive(group_id);
4852   SyncOnMainLoop();
4853   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
4854   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
4855   Mock::VerifyAndClearExpectations(mock_codec_manager_);
4856 }
4857 
TEST_F(UnicastTest,GroupSetActive_SinkPacksEmpty)4858 TEST_F(UnicastTest, GroupSetActive_SinkPacksEmpty) {
4859   const RawAddress test_address0 = GetTestAddress(0);
4860   int group_id = bluetooth::groups::kGroupUnknown;
4861   empty_sink_pack_ = true;
4862 
4863   /**
4864    * In this test we want to make sure that Available context change reach Java
4865    * when group is in Configured state
4866    */
4867 
4868   default_channel_cnt = 1;
4869 
4870   SetSampleDatabaseEarbudsValid(
4871           1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
4872           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
4873           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
4874           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
4875   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4876               OnConnectionState(ConnectionState::CONNECTED, test_address0))
4877           .Times(1);
4878   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4879               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
4880           .WillOnce(DoAll(SaveArg<1>(&group_id)));
4881 
4882   ConnectLeAudio(test_address0);
4883   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
4884 
4885   // Audio sessions are started only when device gets active
4886   std::vector<btle_audio_codec_config_t> empty_confs;
4887 
4888   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4889               OnAudioGroupSelectableCodecConf(group_id, _, empty_confs))
4890           .Times(1);
4891   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
4892   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
4893 
4894   EXPECT_CALL(*mock_codec_manager_,
4895               UpdateActiveUnicastAudioHalClient(mock_le_audio_source_hal_client_,
4896                                                 mock_le_audio_sink_hal_client_, true))
4897           .Times(1);
4898 
4899   LeAudioClient::Get()->GroupSetActive(group_id);
4900   SyncOnMainLoop();
4901   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
4902   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
4903   Mock::VerifyAndClearExpectations(mock_codec_manager_);
4904 }
4905 
TEST_F(UnicastTest,GroupSetActive_SourcePacksEmpty)4906 TEST_F(UnicastTest, GroupSetActive_SourcePacksEmpty) {
4907   const RawAddress test_address0 = GetTestAddress(0);
4908   int group_id = bluetooth::groups::kGroupUnknown;
4909   empty_source_pack_ = true;
4910 
4911   /**
4912    * In this test we want to make sure that Available context change reach Java
4913    * when group is in Configured state
4914    */
4915 
4916   default_channel_cnt = 1;
4917 
4918   SetSampleDatabaseEarbudsValid(
4919           1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
4920           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
4921           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
4922           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
4923   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4924               OnConnectionState(ConnectionState::CONNECTED, test_address0))
4925           .Times(1);
4926   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4927               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
4928           .WillOnce(DoAll(SaveArg<1>(&group_id)));
4929 
4930   ConnectLeAudio(test_address0);
4931   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
4932 
4933   // Audio sessions are started only when device gets active
4934   std::vector<btle_audio_codec_config_t> empty_confs;
4935 
4936   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4937               OnAudioGroupSelectableCodecConf(group_id, empty_confs, _))
4938           .Times(1);
4939   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
4940   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
4941   LeAudioClient::Get()->GroupSetActive(group_id);
4942   SyncOnMainLoop();
4943   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
4944   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
4945 }
4946 
TEST_F(UnicastTest,GroupSetActive_and_InactiveDuringStreamConfiguration)4947 TEST_F(UnicastTest, GroupSetActive_and_InactiveDuringStreamConfiguration) {
4948   const RawAddress test_address0 = GetTestAddress(0);
4949   int group_id = bluetooth::groups::kGroupUnknown;
4950   empty_source_pack_ = true;
4951 
4952   /**
4953    * In this test we want to make sure that StopStream is called when group is set to inactive
4954    * while being between IDLE and CONFIGURED state
4955    */
4956 
4957   default_channel_cnt = 1;
4958 
4959   SetSampleDatabaseEarbudsValid(
4960           1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
4961           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
4962           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
4963           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
4964   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4965               OnConnectionState(ConnectionState::CONNECTED, test_address0))
4966           .Times(1);
4967   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4968               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
4969           .WillOnce(DoAll(SaveArg<1>(&group_id)));
4970 
4971   ConnectLeAudio(test_address0);
4972   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
4973 
4974   EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, _)).Times(1);
4975 
4976   stay_at_qos_config_in_start_stream = true;
4977 
4978   LeAudioClient::Get()->GroupSetActive(group_id);
4979   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id, AUDIO_SOURCE_INVALID, false,
4980                  false);
4981 
4982   SyncOnMainLoop();
4983 
4984   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(1);
4985   LeAudioClient::Get()->GroupSetActive(bluetooth::groups::kGroupUnknown);
4986 
4987   SyncOnMainLoop();
4988   Mock::VerifyAndClearExpectations(&mock_state_machine_);
4989 }
4990 
TEST_F(UnicastTest,GroupSetActive_and_GroupSetInactive_DuringPhoneCall)4991 TEST_F(UnicastTest, GroupSetActive_and_GroupSetInactive_DuringPhoneCall) {
4992   com::android::bluetooth::flags::provider_->leaudio_improve_switch_during_phone_call(true);
4993   const RawAddress test_address0 = GetTestAddress(0);
4994   int group_id = bluetooth::groups::kGroupUnknown;
4995 
4996   /**
4997    * Scenario:
4998    * 1. Call is started
4999    * 2. Group is set active - it is expected the state machine to be instructed to Configure to Qos
5000    * 3. Group is set to inactive - it is expected that state machine is instructed to stop *
5001    */
5002 
5003   default_channel_cnt = 1;
5004 
5005   SetSampleDatabaseEarbudsValid(
5006           1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
5007           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
5008           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
5009           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
5010   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5011               OnConnectionState(ConnectionState::CONNECTED, test_address0))
5012           .Times(1);
5013   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5014               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
5015           .WillOnce(DoAll(SaveArg<1>(&group_id)));
5016 
5017   ConnectLeAudio(test_address0);
5018   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
5019 
5020   EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, _)).Times(0);
5021   EXPECT_CALL(mock_state_machine_, ConfigureStream(_, _, _, _, true)).Times(1);
5022 
5023   log::info("Call is started and group is getting Active");
5024   LeAudioClient::Get()->SetInCall(true);
5025   LeAudioClient::Get()->GroupSetActive(group_id);
5026 
5027   SyncOnMainLoop();
5028   Mock::VerifyAndClearExpectations(&mock_state_machine_);
5029 
5030   log::info("Group is getting inctive");
5031   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(1);
5032   LeAudioClient::Get()->GroupSetActive(bluetooth::groups::kGroupUnknown);
5033 
5034   SyncOnMainLoop();
5035   Mock::VerifyAndClearExpectations(&mock_state_machine_);
5036 }
5037 
TEST_F(UnicastTest,GroupSetActive_DuringPhoneCall_ThenResume)5038 TEST_F(UnicastTest, GroupSetActive_DuringPhoneCall_ThenResume) {
5039   com::android::bluetooth::flags::provider_->leaudio_improve_switch_during_phone_call(true);
5040   const RawAddress test_address0 = GetTestAddress(0);
5041   int group_id = bluetooth::groups::kGroupUnknown;
5042 
5043   /**
5044    * Scenario:
5045    * 1. Call is started
5046    * 2. Group is set active - it is expected the state machine to be instructed to Configure to Qos
5047    * 3. Audio Framework callse Resume - expect stream is started.
5048    * 4. Group is set to inactive - it is expected that state machine is instructed to stop *
5049    */
5050 
5051   default_channel_cnt = 1;
5052 
5053   SetSampleDatabaseEarbudsValid(
5054           1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
5055           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
5056           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
5057           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
5058   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5059               OnConnectionState(ConnectionState::CONNECTED, test_address0))
5060           .Times(1);
5061   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5062               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
5063           .WillOnce(DoAll(SaveArg<1>(&group_id)));
5064 
5065   ConnectLeAudio(test_address0);
5066   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
5067 
5068   EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, _)).Times(0);
5069   EXPECT_CALL(mock_state_machine_, ConfigureStream(_, _, _, _, true)).Times(1);
5070 
5071   log::info("Call is started and group is getting Active");
5072   LeAudioClient::Get()->SetInCall(true);
5073   LeAudioClient::Get()->GroupSetActive(group_id);
5074 
5075   SyncOnMainLoop();
5076   Mock::VerifyAndClearExpectations(&mock_state_machine_);
5077 
5078   log::info("AF resumes the stream");
5079   /* Simulate resume and expect StartStream to be called.
5080    * Do not expect confirmation on resume, as this part is not mocked on the state machine
5081    */
5082   EXPECT_CALL(mock_state_machine_, StartStream(_, LeAudioContextType::CONVERSATIONAL, _, _))
5083           .Times(1);
5084   LocalAudioSourceResume(true, false);
5085   SyncOnMainLoop();
5086   Mock::VerifyAndClearExpectations(&mock_state_machine_);
5087 
5088   log::info("Group is getting inactive");
5089   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(1);
5090   LeAudioClient::Get()->GroupSetActive(bluetooth::groups::kGroupUnknown);
5091 
5092   SyncOnMainLoop();
5093   Mock::VerifyAndClearExpectations(&mock_state_machine_);
5094 }
5095 
TEST_F(UnicastTest,ChangeAvailableContextTypeWhenInCodecConfigured)5096 TEST_F(UnicastTest, ChangeAvailableContextTypeWhenInCodecConfigured) {
5097   const RawAddress test_address0 = GetTestAddress(0);
5098   int group_id = bluetooth::groups::kGroupUnknown;
5099 
5100   /**
5101    * In this test we want to make sure that Available context change reach Java
5102    * when group is in Configured state
5103    */
5104 
5105   default_channel_cnt = 1;
5106 
5107   SetSampleDatabaseEarbudsValid(
5108           1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
5109           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
5110           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
5111           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
5112   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5113               OnConnectionState(ConnectionState::CONNECTED, test_address0))
5114           .Times(1);
5115   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5116               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
5117           .WillOnce(DoAll(SaveArg<1>(&group_id)));
5118 
5119   ConnectLeAudio(test_address0);
5120   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
5121 
5122   // Audio sessions are started only when device gets active
5123   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
5124   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
5125   LeAudioClient::Get()->GroupSetActive(group_id);
5126   SyncOnMainLoop();
5127 
5128   EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, _)).Times(1);
5129 
5130   UpdateLocalSinkMetadata(AUDIO_SOURCE_MIC);
5131   LocalAudioSinkResume();
5132 
5133   SyncOnMainLoop();
5134   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
5135   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
5136   Mock::VerifyAndClearExpectations(&mock_state_machine_);
5137 
5138   // Verify Data transfer on local audio sink which is started
5139   constexpr uint8_t cis_count_out = 0;
5140   constexpr uint8_t cis_count_in = 1;
5141   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 0, 40);
5142 
5143   // Remember group to set the state after stopping the stream
5144   ASSERT_NE(0lu, streaming_groups.count(group_id));
5145   auto group = streaming_groups.at(group_id);
5146 
5147   SyncOnMainLoop();
5148   StopStreaming(group_id, true);
5149   SyncOnMainLoop();
5150 
5151   // simulate suspend timeout passed, alarm executing
5152   fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
5153   SyncOnMainLoop();
5154 
5155   // Simulate state Configured
5156   group->SetState(types::AseState::BTA_LE_AUDIO_ASE_STATE_CODEC_CONFIGURED);
5157 
5158   EXPECT_CALL(mock_audio_hal_client_callbacks_, OnAudioConf(_, _, _, _, _));
5159 
5160   /* Check if available context will be sent to Java */
5161   auto sink_available_context = types::kLeAudioContextAllRemoteSinkOnly;
5162   auto source_available_context = types::kLeAudioContextAllRemoteSource;
5163 
5164   InjectAvailableContextTypes(test_address0, 1, sink_available_context, source_available_context);
5165 
5166   SyncOnMainLoop();
5167   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
5168 }
5169 
TEST_F(UnicastTest,TestUpdateConfigurationCallbackWhileStreaming)5170 TEST_F(UnicastTest, TestUpdateConfigurationCallbackWhileStreaming) {
5171   const RawAddress test_address0 = GetTestAddress(0);
5172   int group_id = bluetooth::groups::kGroupUnknown;
5173 
5174   SetSampleDatabaseEarbudsValid(
5175           1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
5176           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
5177           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
5178           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
5179   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5180               OnConnectionState(ConnectionState::CONNECTED, test_address0))
5181           .Times(1);
5182   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5183               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
5184           .WillOnce(DoAll(SaveArg<1>(&group_id)));
5185 
5186   ConnectLeAudio(test_address0);
5187   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
5188 
5189   // Start streaming
5190   LeAudioClient::Get()->GroupSetActive(group_id);
5191   SyncOnMainLoop();
5192 
5193   EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, _)).Times(1);
5194   EXPECT_CALL(mock_audio_hal_client_callbacks_, OnAudioGroupCurrentCodecConf(group_id, _, _))
5195           .Times(1);
5196   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
5197 
5198   SyncOnMainLoop();
5199   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
5200   Mock::VerifyAndClearExpectations(&mock_state_machine_);
5201   SyncOnMainLoop();
5202 
5203   // When metadata update happen, there should be no configuration change
5204   // callback sent
5205   EXPECT_CALL(mock_audio_hal_client_callbacks_, OnAudioGroupCurrentCodecConf(group_id, _, _))
5206           .Times(0);
5207 
5208   EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, _)).Times(1);
5209   UpdateLocalSourceMetadata(AUDIO_USAGE_ALARM, AUDIO_CONTENT_TYPE_UNKNOWN);
5210 
5211   // Inject STREAMING Status from state machine.
5212   auto group = streaming_groups.at(group_id);
5213   do_in_main_thread(base::BindOnce(
5214           [](int group_id,
5215              bluetooth::le_audio::LeAudioGroupStateMachine::Callbacks* state_machine_callbacks,
5216              LeAudioDeviceGroup* /*group*/) {
5217             state_machine_callbacks->StatusReportCb(group_id, GroupStreamStatus::STREAMING);
5218           },
5219           group_id, base::Unretained(this->state_machine_callbacks_), std::move(group)));
5220 
5221   SyncOnMainLoop();
5222   Mock::VerifyAndClearExpectations(&mock_state_machine_);
5223   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
5224 }
5225 
TEST_F(UnicastTest,TestDeactivateWhileStartingStream)5226 TEST_F(UnicastTest, TestDeactivateWhileStartingStream) {
5227   const RawAddress test_address0 = GetTestAddress(0);
5228   int group_id = bluetooth::groups::kGroupUnknown;
5229 
5230   SetSampleDatabaseEarbudsValid(
5231           1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
5232           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
5233           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
5234           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
5235   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5236               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
5237           .WillOnce(DoAll(SaveArg<1>(&group_id)));
5238 
5239   ConnectLeAudio(test_address0);
5240   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
5241 
5242   // Start streaming
5243   LeAudioClient::Get()->GroupSetActive(group_id);
5244   SyncOnMainLoop();
5245   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
5246 
5247   // Deactivate while starting to stream
5248   LeAudioClient::Get()->GroupSetActive(bluetooth::groups::kGroupUnknown);
5249 
5250   // Inject STREAMING Status from state machine.
5251   auto group = streaming_groups.at(group_id);
5252   do_in_main_thread(base::BindOnce(
5253           [](int group_id,
5254              bluetooth::le_audio::LeAudioGroupStateMachine::Callbacks* state_machine_callbacks,
5255              LeAudioDeviceGroup* /*group*/) {
5256             state_machine_callbacks->StatusReportCb(group_id, GroupStreamStatus::STREAMING);
5257           },
5258           group_id, base::Unretained(this->state_machine_callbacks_), std::move(group)));
5259   SyncOnMainLoop();
5260 }
5261 
TEST_F(UnicastTest,RemoveNodeWhileStreaming)5262 TEST_F(UnicastTest, RemoveNodeWhileStreaming) {
5263   const RawAddress test_address0 = GetTestAddress(0);
5264   int group_id = bluetooth::groups::kGroupUnknown;
5265 
5266   SetSampleDatabaseEarbudsValid(
5267           1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
5268           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
5269           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
5270           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
5271   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5272               OnConnectionState(ConnectionState::CONNECTED, test_address0))
5273           .Times(1);
5274   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5275               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
5276           .WillOnce(DoAll(SaveArg<1>(&group_id)));
5277 
5278   ConnectLeAudio(test_address0);
5279   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
5280 
5281   // Start streaming
5282   constexpr uint8_t cis_count_out = 1;
5283   constexpr uint8_t cis_count_in = 0;
5284 
5285   constexpr int gmcs_ccid = 1;
5286   constexpr int gtbs_ccid = 2;
5287 
5288   // Audio sessions are started only when device gets active
5289   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
5290   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
5291   LeAudioClient::Get()->SetCcidInformation(gmcs_ccid, 4 /* Media */);
5292   LeAudioClient::Get()->SetCcidInformation(gtbs_ccid, 2 /* Phone */);
5293   LeAudioClient::Get()->GroupSetActive(group_id);
5294   SyncOnMainLoop();
5295 
5296   types::BidirectionalPair<std::vector<uint8_t>> ccids = {.sink = {gmcs_ccid}, .source = {}};
5297   EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, ccids)).Times(1);
5298 
5299   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
5300 
5301   SyncOnMainLoop();
5302   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
5303   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
5304   Mock::VerifyAndClearExpectations(&mock_state_machine_);
5305   SyncOnMainLoop();
5306 
5307   // Verify Data transfer on one audio source cis
5308   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
5309 
5310   EXPECT_CALL(mock_groups_module_, RemoveDevice(test_address0, group_id)).Times(1);
5311   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(1);
5312   EXPECT_CALL(mock_state_machine_, ProcessHciNotifAclDisconnected(_, _)).Times(1);
5313   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5314               OnGroupNodeStatus(test_address0, group_id, GroupNodeStatus::REMOVED));
5315   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5316               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
5317           .Times(1);
5318 
5319   LeAudioClient::Get()->GroupRemoveNode(group_id, test_address0);
5320 
5321   SyncOnMainLoop();
5322   Mock::VerifyAndClearExpectations(&mock_groups_module_);
5323   Mock::VerifyAndClearExpectations(&mock_state_machine_);
5324   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
5325 }
5326 
TEST_F(UnicastTest,InactiveDeviceOnInternalStateMachineError)5327 TEST_F(UnicastTest, InactiveDeviceOnInternalStateMachineError) {
5328   const RawAddress test_address0 = GetTestAddress(0);
5329   int group_id = bluetooth::groups::kGroupUnknown;
5330 
5331   SetSampleDatabaseEarbudsValid(
5332           1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
5333           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
5334           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
5335           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
5336   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5337               OnConnectionState(ConnectionState::CONNECTED, test_address0))
5338           .Times(1);
5339   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5340               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
5341           .WillOnce(DoAll(SaveArg<1>(&group_id)));
5342 
5343   ConnectLeAudio(test_address0);
5344   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
5345 
5346   // Start streaming
5347   constexpr uint8_t cis_count_out = 1;
5348   constexpr uint8_t cis_count_in = 0;
5349 
5350   constexpr int gmcs_ccid = 1;
5351   constexpr int gtbs_ccid = 2;
5352 
5353   // Audio sessions are started only when device gets active
5354   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
5355   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
5356   LeAudioClient::Get()->SetCcidInformation(gmcs_ccid, 4 /* Media */);
5357   LeAudioClient::Get()->SetCcidInformation(gtbs_ccid, 2 /* Phone */);
5358   LeAudioClient::Get()->GroupSetActive(group_id);
5359   SyncOnMainLoop();
5360 
5361   types::BidirectionalPair<std::vector<uint8_t>> ccids = {.sink = {gmcs_ccid}, .source = {}};
5362   EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, ccids)).Times(1);
5363 
5364   btle_audio_codec_config_t empty_conf{};
5365   btle_audio_codec_config_t output_config = {
5366           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
5367           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_48000HZ,
5368           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
5369           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_2,
5370           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
5371           .octets_per_frame = 120};
5372 
5373   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5374               OnAudioGroupCurrentCodecConf(group_id, empty_conf, output_config))
5375           .Times(1);
5376 
5377   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
5378 
5379   SyncOnMainLoop();
5380   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
5381   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
5382   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
5383   Mock::VerifyAndClearExpectations(&mock_state_machine_);
5384   SyncOnMainLoop();
5385 
5386   // Verify Data transfer on one audio source cis
5387   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
5388 
5389   EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop()).Times(1);
5390   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Stop()).Times(1);
5391 
5392   EXPECT_CALL(mock_audio_hal_client_callbacks_, OnGroupStatus(group_id, GroupStatus::INACTIVE))
5393           .Times(1);
5394 
5395   /* This is internal error of the state machine */
5396   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::RELEASING);
5397 
5398   SyncOnMainLoop();
5399   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
5400   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
5401   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
5402 }
5403 
TEST_F(UnicastTest,GroupingAddTwiceNoRemove)5404 TEST_F(UnicastTest, GroupingAddTwiceNoRemove) {
5405   // Earbud connects without known grouping
5406   uint8_t group_id0 = bluetooth::groups::kGroupUnknown;
5407   const RawAddress test_address0 = GetTestAddress(0);
5408   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true))
5409           .WillOnce(Return())
5410           .RetiresOnSaturation();
5411   ConnectNonCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
5412                        codec_spec_conf::kLeAudioLocationFrontLeft);
5413 
5414   group_id0 = MockDeviceGroups::DeviceGroups::Get()->GetGroupId(test_address0);
5415 
5416   // Earbud connects without known grouping
5417   uint8_t group_id1 = bluetooth::groups::kGroupUnknown;
5418   const RawAddress test_address1 = GetTestAddress(1);
5419   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true))
5420           .WillOnce(Return())
5421           .RetiresOnSaturation();
5422   ConnectNonCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
5423                        codec_spec_conf::kLeAudioLocationFrontRight);
5424 
5425   Mock::VerifyAndClearExpectations(&mock_btif_storage_);
5426 
5427   group_id1 = MockDeviceGroups::DeviceGroups::Get()->GetGroupId(test_address1);
5428   // Verify individual groups
5429   ASSERT_NE(group_id0, bluetooth::groups::kGroupUnknown);
5430   ASSERT_NE(group_id1, bluetooth::groups::kGroupUnknown);
5431   ASSERT_NE(group_id0, group_id1);
5432   ASSERT_EQ(LeAudioClient::Get()->GetGroupDevices(group_id0).size(), 1u);
5433   ASSERT_EQ(LeAudioClient::Get()->GetGroupDevices(group_id1).size(), 1u);
5434 
5435   // Expectations on reassigning second earbud to the first group
5436   int dev1_storage_group = bluetooth::groups::kGroupUnknown;
5437   int dev1_new_group = bluetooth::groups::kGroupUnknown;
5438 
5439   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5440               OnGroupNodeStatus(test_address1, group_id1, GroupNodeStatus::REMOVED))
5441           .Times(AtLeast(1));
5442   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5443               OnGroupNodeStatus(test_address1, _, GroupNodeStatus::ADDED))
5444           .WillRepeatedly(SaveArg<1>(&dev1_new_group));
5445 
5446   // FIXME: We should expect removal with group_id context. No such API exists.
5447   EXPECT_CALL(mock_groups_module_, RemoveDevice(test_address1, group_id1)).Times(AtLeast(1));
5448   EXPECT_CALL(mock_groups_module_, AddDevice(test_address1, _, _)).Times(AnyNumber());
5449   EXPECT_CALL(mock_groups_module_, AddDevice(test_address1, _, group_id0)).Times(1);
5450 
5451   // Regroup device: assign new group without removing it from the first one
5452   LeAudioClient::Get()->GroupAddNode(group_id0, test_address1);
5453   SyncOnMainLoop();
5454   Mock::VerifyAndClearExpectations(&mock_groups_module_);
5455 
5456   dev1_storage_group = MockDeviceGroups::DeviceGroups::Get()->GetGroupId(test_address1);
5457 
5458   // Verify regrouping results
5459   EXPECT_EQ(dev1_new_group, group_id0);
5460   EXPECT_EQ(dev1_new_group, dev1_storage_group);
5461   ASSERT_EQ(LeAudioClient::Get()->GetGroupDevices(group_id1).size(), 0u);
5462   ASSERT_EQ(LeAudioClient::Get()->GetGroupDevices(group_id0).size(), 2u);
5463   std::vector<RawAddress> devs = LeAudioClient::Get()->GetGroupDevices(group_id0);
5464   ASSERT_NE(std::find(devs.begin(), devs.end(), test_address0), devs.end());
5465   ASSERT_NE(std::find(devs.begin(), devs.end(), test_address1), devs.end());
5466 }
5467 
TEST_F(UnicastTest,RemoveTwoEarbudsCsisGrouped)5468 TEST_F(UnicastTest, RemoveTwoEarbudsCsisGrouped) {
5469   uint8_t group_size = 2;
5470   int group_id0 = 2;
5471   int group_id1 = 3;
5472 
5473   // Report working CSIS
5474   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
5475 
5476   // First group - First earbud
5477   const RawAddress test_address0 = GetTestAddress(0);
5478   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
5479   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
5480                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id0, 1 /* rank*/);
5481 
5482   // First group - Second earbud
5483   const RawAddress test_address1 = GetTestAddress(1);
5484   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
5485   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
5486                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id0, 2 /* rank*/,
5487                     true /*connect_through_csis*/);
5488 
5489   // Second group - First earbud
5490   const RawAddress test_address2 = GetTestAddress(2);
5491   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address2, true)).Times(1);
5492   ConnectCsisDevice(test_address2, 3 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
5493                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id1, 1 /* rank*/);
5494 
5495   // Second group - Second earbud
5496   const RawAddress test_address3 = GetTestAddress(3);
5497   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address3, true)).Times(1);
5498   ConnectCsisDevice(test_address3, 4 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
5499                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id1, 2 /* rank*/,
5500                     true /*connect_through_csis*/);
5501 
5502   // First group - verify grouping information
5503   std::vector<RawAddress> group0_devs = LeAudioClient::Get()->GetGroupDevices(group_id0);
5504   ASSERT_NE(std::find(group0_devs.begin(), group0_devs.end(), test_address0), group0_devs.end());
5505   ASSERT_NE(std::find(group0_devs.begin(), group0_devs.end(), test_address1), group0_devs.end());
5506 
5507   // Second group - verify grouping information
5508   std::vector<RawAddress> group1_devs = LeAudioClient::Get()->GetGroupDevices(group_id1);
5509   ASSERT_NE(std::find(group1_devs.begin(), group1_devs.end(), test_address2), group1_devs.end());
5510   ASSERT_NE(std::find(group1_devs.begin(), group1_devs.end(), test_address3), group1_devs.end());
5511   Mock::VerifyAndClearExpectations(&mock_btif_storage_);
5512 
5513   // Expect one of the groups to be dropped and devices to be disconnected
5514   EXPECT_CALL(mock_groups_module_, RemoveDevice(test_address0, group_id0)).Times(1);
5515   EXPECT_CALL(mock_groups_module_, RemoveDevice(test_address1, group_id0)).Times(1);
5516   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5517               OnGroupNodeStatus(test_address0, group_id0, GroupNodeStatus::REMOVED));
5518   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5519               OnGroupNodeStatus(test_address1, group_id0, GroupNodeStatus::REMOVED));
5520   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5521               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
5522           .Times(1);
5523   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5524               OnConnectionState(ConnectionState::DISCONNECTED, test_address1))
5525           .Times(1);
5526 
5527   EXPECT_CALL(mock_btm_interface_, AclDisconnectFromHandle(1, _)).Times(1);
5528   EXPECT_CALL(mock_btm_interface_, AclDisconnectFromHandle(2, _)).Times(1);
5529 
5530   // Expect the other groups to be left as is
5531   EXPECT_CALL(mock_audio_hal_client_callbacks_, OnGroupStatus(group_id1, _)).Times(0);
5532   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5533               OnConnectionState(ConnectionState::DISCONNECTED, test_address2))
5534           .Times(0);
5535   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5536               OnConnectionState(ConnectionState::DISCONNECTED, test_address3))
5537           .Times(0);
5538 
5539   EXPECT_CALL(mock_btm_interface_, AclDisconnectFromHandle(3, _)).Times(0);
5540   EXPECT_CALL(mock_btm_interface_, AclDisconnectFromHandle(4, _)).Times(0);
5541 
5542   do_in_main_thread(base::BindOnce(&LeAudioClient::GroupDestroy,
5543                                    base::Unretained(LeAudioClient::Get()), group_id0));
5544 
5545   SyncOnMainLoop();
5546   Mock::VerifyAndClearExpectations(&mock_btif_storage_);
5547   Mock::VerifyAndClearExpectations(&mock_btm_interface_);
5548 }
5549 
TEST_F(UnicastTest,ConnectAfterRemove)5550 TEST_F(UnicastTest, ConnectAfterRemove) {
5551   const RawAddress test_address0 = GetTestAddress(0);
5552   int group_id = bluetooth::groups::kGroupUnknown;
5553   uint16_t conn_id = 1;
5554 
5555   SetSampleDatabaseEarbudsValid(
5556           conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo,
5557           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
5558           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
5559           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
5560   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5561               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
5562           .Times(1);
5563 
5564   /* RemoveDevice */
5565   do_in_main_thread(base::BindOnce(
5566           [](LeAudioClient* client, const RawAddress& test_address0) {
5567             client->RemoveDevice(test_address0);
5568           },
5569           LeAudioClient::Get(), test_address0));
5570   SyncOnMainLoop();
5571 
5572   ON_CALL(mock_btm_interface_, IsLinkKeyKnown(_, _)).WillByDefault(DoAll(Return(false)));
5573 
5574   do_in_main_thread(base::BindOnce(&LeAudioClient::Connect, base::Unretained(LeAudioClient::Get()),
5575                                    test_address0));
5576   SyncOnMainLoop();
5577 
5578   Mock::VerifyAndClearExpectations(&mock_btif_storage_);
5579   Mock::VerifyAndClearExpectations(&mock_gatt_queue_);
5580   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
5581 }
5582 
TEST_F(UnicastTest,RemoveDeviceWhenConnected)5583 TEST_F(UnicastTest, RemoveDeviceWhenConnected) {
5584   const RawAddress test_address0 = GetTestAddress(0);
5585   int group_id = bluetooth::groups::kGroupUnknown;
5586   uint16_t conn_id = 1;
5587 
5588   SetSampleDatabaseEarbudsValid(
5589           conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo,
5590           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
5591           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
5592           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
5593   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5594               OnConnectionState(ConnectionState::CONNECTED, test_address0))
5595           .Times(1);
5596   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5597               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
5598           .WillOnce(DoAll(SaveArg<1>(&group_id)));
5599   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
5600   ConnectLeAudio(test_address0);
5601   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
5602 
5603   Mock::VerifyAndClearExpectations(&mock_btif_storage_);
5604   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
5605 
5606   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, false)).Times(1);
5607   EXPECT_CALL(mock_gatt_queue_, Clean(conn_id)).Times(AtLeast(1));
5608   EXPECT_CALL(mock_btm_interface_, AclDisconnectFromHandle(1, _)).Times(1);
5609 
5610   /*
5611    * StopStream will put calls on main_loop so to keep the correct order
5612    * of operations and to avoid races we put the test command on main_loop as
5613    * well.
5614    */
5615   do_in_main_thread(base::BindOnce(
5616           [](LeAudioClient* client, const RawAddress& test_address0) {
5617             client->RemoveDevice(test_address0);
5618           },
5619           LeAudioClient::Get(), test_address0));
5620   SyncOnMainLoop();
5621 
5622   Mock::VerifyAndClearExpectations(&mock_btif_storage_);
5623   Mock::VerifyAndClearExpectations(&mock_gatt_queue_);
5624   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
5625 }
5626 
TEST_F(UnicastTest,RemoveDeviceWhenUserConnecting)5627 TEST_F(UnicastTest, RemoveDeviceWhenUserConnecting) {
5628   const RawAddress test_address0 = GetTestAddress(0);
5629   uint16_t conn_id = 1;
5630 
5631   /* Prepare  mock to not inject connect event so the device can stay in
5632    * CONNECTING state*/
5633   ON_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_DIRECT_CONNECTION, _))
5634           .WillByDefault(DoAll(Return()));
5635 
5636   SetSampleDatabaseEarbudsValid(
5637           conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo,
5638           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
5639           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
5640           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
5641   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5642               OnConnectionState(ConnectionState::CONNECTED, test_address0))
5643           .Times(0);
5644   ConnectLeAudio(test_address0, true, false);
5645 
5646   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
5647 
5648   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, true)).Times(1);
5649   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, false)).Times(1);
5650   EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address0, _, _)).Times(0);
5651 
5652   /*
5653    * StopStream will put calls on main_loop so to keep the correct order
5654    * of operations and to avoid races we put the test command on main_loop as
5655    * well.
5656    */
5657   do_in_main_thread(base::BindOnce(
5658           [](LeAudioClient* client, const RawAddress& test_address0) {
5659             client->RemoveDevice(test_address0);
5660           },
5661           LeAudioClient::Get(), test_address0));
5662 
5663   SyncOnMainLoop();
5664 
5665   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
5666 }
5667 
TEST_F(UnicastTest,RemoveDeviceWhenAutoConnectingWithTargetedAnnouncements)5668 TEST_F(UnicastTest, RemoveDeviceWhenAutoConnectingWithTargetedAnnouncements) {
5669   const RawAddress test_address0 = GetTestAddress(0);
5670   uint16_t conn_id = 1;
5671 
5672   /* Scenario
5673    * 1. Connect device
5674    * 2. Disconnect by remote device -> this shall start Reconnection Using TA
5675    * 3. Remove device
5676    */
5677   SetSampleDatabaseEarbudsValid(
5678           conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo,
5679           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
5680           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
5681           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
5682 
5683   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5684               OnConnectionState(ConnectionState::CONNECTED, test_address0))
5685           .Times(1);
5686   ConnectLeAudio(test_address0, true);
5687 
5688   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
5689   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
5690 
5691   EXPECT_CALL(mock_gatt_interface_,
5692               Open(gatt_if, test_address0, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _))
5693           .Times(1);
5694 
5695   // Inject disconnected event, Reconnect with TA shall start
5696   InjectDisconnectedEvent(conn_id);
5697   SyncOnMainLoop();
5698   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
5699 
5700   // Remove device when being in auto connect state.
5701   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, true)).Times(1);
5702   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, false)).Times(1);
5703   EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address0, _, _)).Times(0);
5704 
5705   do_in_main_thread(base::BindOnce(
5706           [](LeAudioClient* client, const RawAddress& test_address0) {
5707             client->RemoveDevice(test_address0);
5708           },
5709           LeAudioClient::Get(), test_address0));
5710 
5711   SyncOnMainLoop();
5712 
5713   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
5714 }
5715 
TEST_F(UnicastTest,RemoveDeviceWhenAutoConnectingAfterConnectionTimeout)5716 TEST_F(UnicastTest, RemoveDeviceWhenAutoConnectingAfterConnectionTimeout) {
5717   const RawAddress test_address0 = GetTestAddress(0);
5718   uint16_t conn_id = 1;
5719 
5720   /* Scenario
5721    * 1. Connect device
5722    * 2. Disconnect remote device with connection timeout -> this shall start direct connect
5723    * 3. Remove device
5724    */
5725   SetSampleDatabaseEarbudsValid(
5726           conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo,
5727           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
5728           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
5729           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
5730 
5731   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5732               OnConnectionState(ConnectionState::CONNECTED, test_address0))
5733           .Times(1);
5734   ConnectLeAudio(test_address0, true);
5735 
5736   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
5737   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
5738 
5739   // Prepare mock for direct connect and inject connection timeout
5740   ON_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_DIRECT_CONNECTION, _))
5741           .WillByDefault(DoAll(Return()));
5742   EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address0, BTM_BLE_DIRECT_CONNECTION, _))
5743           .Times(1);
5744 
5745   InjectDisconnectedEvent(conn_id, GATT_CONN_TIMEOUT);
5746   SyncOnMainLoop();
5747   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
5748 
5749   // Remove device when being in auto connect state after connection timeout
5750   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, true)).Times(1);
5751   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, false)).Times(1);
5752   EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address0, _, _)).Times(0);
5753 
5754   do_in_main_thread(base::BindOnce(
5755           [](LeAudioClient* client, const RawAddress& test_address0) {
5756             client->RemoveDevice(test_address0);
5757           },
5758           LeAudioClient::Get(), test_address0));
5759 
5760   SyncOnMainLoop();
5761 
5762   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
5763 }
5764 
TEST_F(UnicastTest,RemoveDeviceWhenGettingConnectionReady)5765 TEST_F(UnicastTest, RemoveDeviceWhenGettingConnectionReady) {
5766   const RawAddress test_address0 = GetTestAddress(0);
5767   uint16_t conn_id = 1;
5768 
5769   /* Prepare  mock to not inject Service Search Complete*/
5770   ON_CALL(mock_gatt_interface_, ServiceSearchRequest(_, _)).WillByDefault(DoAll(Return()));
5771 
5772   SetSampleDatabaseEarbudsValid(
5773           conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo,
5774           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
5775           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
5776           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
5777   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5778               OnConnectionState(ConnectionState::CONNECTED, test_address0))
5779           .Times(0);
5780   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, false)).Times(0);
5781   ConnectLeAudio(test_address0);
5782 
5783   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
5784   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
5785 
5786   EXPECT_CALL(mock_gatt_queue_, Clean(conn_id)).Times(AtLeast(1));
5787   EXPECT_CALL(mock_gatt_interface_, Close(conn_id)).Times(1);
5788 
5789   /* Cancel should be called in RemoveDevice */
5790   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, false)).Times(1);
5791   EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address0, _, _)).Times(0);
5792 
5793   /*
5794    * StopStream will put calls on main_loop so to keep the correct order
5795    * of operations and to avoid races we put the test command on main_loop as
5796    * well.
5797    */
5798   do_in_main_thread(base::BindOnce(
5799           [](LeAudioClient* client, const RawAddress& test_address0) {
5800             client->RemoveDevice(test_address0);
5801           },
5802           LeAudioClient::Get(), test_address0));
5803 
5804   SyncOnMainLoop();
5805 
5806   Mock::VerifyAndClearExpectations(&mock_btif_storage_);
5807   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
5808 }
5809 
TEST_F(UnicastTest,DisconnectDeviceWhenConnected)5810 TEST_F(UnicastTest, DisconnectDeviceWhenConnected) {
5811   const RawAddress test_address0 = GetTestAddress(0);
5812   int group_id = bluetooth::groups::kGroupUnknown;
5813   uint16_t conn_id = 1;
5814 
5815   SetSampleDatabaseEarbudsValid(
5816           conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo,
5817           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
5818           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
5819           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
5820   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5821               OnConnectionState(ConnectionState::CONNECTED, test_address0))
5822           .Times(1);
5823   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5824               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
5825           .WillOnce(DoAll(SaveArg<1>(&group_id)));
5826   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
5827   ConnectLeAudio(test_address0);
5828   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
5829 
5830   Mock::VerifyAndClearExpectations(&mock_btif_storage_);
5831   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
5832 
5833   /* for Target announcements AutoConnect is always there, until
5834    * device is removed
5835    */
5836   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, false)).Times(0);
5837   EXPECT_CALL(mock_gatt_queue_, Clean(conn_id)).Times(AtLeast(1));
5838   EXPECT_CALL(mock_btm_interface_, AclDisconnectFromHandle(1, _)).Times(1);
5839 
5840   LeAudioClient::Get()->Disconnect(test_address0);
5841   SyncOnMainLoop();
5842 
5843   Mock::VerifyAndClearExpectations(&mock_btif_storage_);
5844   Mock::VerifyAndClearExpectations(&mock_gatt_queue_);
5845   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
5846 }
5847 
TEST_F(UnicastTest,DisconnectDeviceWhenConnecting)5848 TEST_F(UnicastTest, DisconnectDeviceWhenConnecting) {
5849   const RawAddress test_address0 = GetTestAddress(0);
5850   uint16_t conn_id = 1;
5851 
5852   /* Prepare  mock to not inject connect event so the device can stay in
5853    * CONNECTING state*/
5854   ON_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_DIRECT_CONNECTION, _))
5855           .WillByDefault(DoAll(Return()));
5856 
5857   SetSampleDatabaseEarbudsValid(
5858           conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo,
5859           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
5860           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
5861           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
5862   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5863               OnConnectionState(ConnectionState::CONNECTED, test_address0))
5864           .Times(0);
5865   ConnectLeAudio(test_address0, true, false);
5866 
5867   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
5868 
5869   /* Prepare on call mock on Close - to not trigger Inject Disconnection, as it
5870    * is done in default mock.
5871    */
5872   ON_CALL(mock_gatt_interface_, Close(_)).WillByDefault(DoAll(Return()));
5873   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, true)).Times(1);
5874   EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address0, _, _)).Times(0);
5875 
5876   LeAudioClient::Get()->Disconnect(test_address0);
5877   SyncOnMainLoop();
5878 
5879   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
5880 }
5881 
TEST_F(UnicastTest,DisconnectDeviceWhenGettingConnectionReady)5882 TEST_F(UnicastTest, DisconnectDeviceWhenGettingConnectionReady) {
5883   const RawAddress test_address0 = GetTestAddress(0);
5884   uint16_t conn_id = global_conn_id;
5885 
5886   /* Prepare  mock to not inject Service Search Complete*/
5887   ON_CALL(mock_gatt_interface_, ServiceSearchRequest(_, _)).WillByDefault(DoAll(Return()));
5888 
5889   SetSampleDatabaseEarbudsValid(
5890           conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo,
5891           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
5892           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
5893           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
5894   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5895               OnConnectionState(ConnectionState::CONNECTED, test_address0))
5896           .Times(0);
5897   ConnectLeAudio(test_address0);
5898 
5899   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
5900   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
5901 
5902   /* TA reconnect is enabled in ConnectLeAudio. Make sure this is not removed */
5903   EXPECT_CALL(mock_gatt_queue_, Clean(conn_id)).Times(AtLeast(1));
5904   EXPECT_CALL(mock_gatt_interface_, Close(conn_id)).Times(1);
5905   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, _)).Times(0);
5906   EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address0, _, _)).Times(0);
5907 
5908   LeAudioClient::Get()->Disconnect(test_address0);
5909   SyncOnMainLoop();
5910 
5911   Mock::VerifyAndClearExpectations(&mock_gatt_queue_);
5912   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
5913 }
5914 
TEST_F(UnicastTest,RemoveWhileStreaming)5915 TEST_F(UnicastTest, RemoveWhileStreaming) {
5916   const RawAddress test_address0 = GetTestAddress(0);
5917   int group_id = bluetooth::groups::kGroupUnknown;
5918 
5919   SetSampleDatabaseEarbudsValid(
5920           1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
5921           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
5922           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
5923           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
5924   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5925               OnConnectionState(ConnectionState::CONNECTED, test_address0))
5926           .Times(1);
5927   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5928               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
5929           .WillOnce(DoAll(SaveArg<1>(&group_id)));
5930 
5931   ConnectLeAudio(test_address0);
5932   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
5933 
5934   // Start streaming
5935   constexpr uint8_t cis_count_out = 1;
5936   constexpr uint8_t cis_count_in = 0;
5937 
5938   constexpr int gmcs_ccid = 1;
5939   constexpr int gtbs_ccid = 2;
5940 
5941   // Audio sessions are started only when device gets active
5942   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
5943   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
5944   LeAudioClient::Get()->SetCcidInformation(gmcs_ccid, 4 /* Media */);
5945   LeAudioClient::Get()->SetCcidInformation(gtbs_ccid, 2 /* Phone */);
5946   LeAudioClient::Get()->GroupSetActive(group_id);
5947   SyncOnMainLoop();
5948 
5949   types::BidirectionalPair<std::vector<uint8_t>> ccids = {.sink = {gmcs_ccid}, .source = {}};
5950   EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, ccids)).Times(1);
5951 
5952   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
5953 
5954   SyncOnMainLoop();
5955   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
5956   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
5957   Mock::VerifyAndClearExpectations(&mock_state_machine_);
5958   SyncOnMainLoop();
5959 
5960   // Verify Data transfer on one audio source cis
5961   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
5962 
5963   EXPECT_CALL(mock_groups_module_, RemoveDevice(test_address0, group_id)).Times(1);
5964 
5965   LeAudioDeviceGroup* group = nullptr;
5966   EXPECT_CALL(mock_state_machine_, ProcessHciNotifAclDisconnected(_, _))
5967           .WillOnce(DoAll(SaveArg<0>(&group)));
5968   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5969               OnGroupNodeStatus(test_address0, group_id, GroupNodeStatus::REMOVED));
5970 
5971   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5972               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
5973           .Times(1);
5974 
5975   /*
5976    * StopStream will put calls on main_loop so to keep the correct order
5977    * of operations and to avoid races we put the test command on main_loop as
5978    * well.
5979    */
5980   do_in_main_thread(base::BindOnce(
5981           [](LeAudioClient* client, const RawAddress& test_address0) {
5982             client->RemoveDevice(test_address0);
5983           },
5984           LeAudioClient::Get(), test_address0));
5985 
5986   SyncOnMainLoop();
5987   Mock::VerifyAndClearExpectations(&mock_groups_module_);
5988   Mock::VerifyAndClearExpectations(&mock_state_machine_);
5989   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
5990 
5991   ASSERT_EQ(group, nullptr);
5992 }
5993 
TEST_F(UnicastTest,DisconnecteWhileAlmostStreaming)5994 TEST_F(UnicastTest, DisconnecteWhileAlmostStreaming) {
5995   const RawAddress test_address0 = GetTestAddress(0);
5996   int group_id = bluetooth::groups::kGroupUnknown;
5997 
5998   SetSampleDatabaseEarbudsValid(
5999           1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
6000           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
6001           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
6002           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
6003   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6004               OnConnectionState(ConnectionState::CONNECTED, test_address0))
6005           .Times(1);
6006   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6007               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
6008           .WillOnce(DoAll(SaveArg<1>(&group_id)));
6009 
6010   ConnectLeAudio(test_address0);
6011   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
6012 
6013   constexpr int gmcs_ccid = 1;
6014   constexpr int gtbs_ccid = 2;
6015 
6016   // Audio sessions are started only when device gets active
6017   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
6018   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
6019   LeAudioClient::Get()->SetCcidInformation(gmcs_ccid, 4 /* Media */);
6020   LeAudioClient::Get()->SetCcidInformation(gtbs_ccid, 2 /* Phone */);
6021   LeAudioClient::Get()->GroupSetActive(group_id);
6022   SyncOnMainLoop();
6023 
6024   types::BidirectionalPair<std::vector<uint8_t>> ccids = {.sink = {gmcs_ccid}, .source = {}};
6025   EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, ccids)).Times(1);
6026 
6027   /* We want here to CIS be established but device not being yet in streaming
6028    * state
6029    */
6030   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
6031 
6032   SyncOnMainLoop();
6033   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6034   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
6035   Mock::VerifyAndClearExpectations(&mock_state_machine_);
6036   SyncOnMainLoop();
6037 
6038   /* This is test code, which will change the group state to the one which
6039    * is required by test
6040    */
6041   ASSERT_NE(0lu, streaming_groups.count(group_id));
6042   auto group_inject = streaming_groups.at(group_id);
6043   group_inject->SetState(types::AseState::BTA_LE_AUDIO_ASE_STATE_ENABLING);
6044 
6045   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(1);
6046 
6047   LeAudioDeviceGroup* group = nullptr;
6048   EXPECT_CALL(mock_state_machine_, ProcessHciNotifAclDisconnected(_, _))
6049           .WillOnce(DoAll(SaveArg<0>(&group)));
6050 
6051   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6052               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
6053           .Times(1);
6054 
6055   /*
6056    * StopStream will put calls on main_loop so to keep the correct order
6057    * of operations and to avoid races we put the test command on main_loop as
6058    * well.
6059    */
6060   do_in_main_thread(
6061           base::BindOnce([](LeAudioClient* client,
6062                             const RawAddress& test_address0) { client->Disconnect(test_address0); },
6063                          LeAudioClient::Get(), test_address0));
6064 
6065   SyncOnMainLoop();
6066   Mock::VerifyAndClearExpectations(&mock_groups_module_);
6067   Mock::VerifyAndClearExpectations(&mock_state_machine_);
6068   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6069 
6070   ASSERT_EQ(group->GetState(), types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE);
6071 }
6072 
TEST_F(UnicastTest,DisconnecteWhileAlmostStreaming_twoDevices)6073 TEST_F(UnicastTest, DisconnecteWhileAlmostStreaming_twoDevices) {
6074   const RawAddress test_address0 = GetTestAddress(0);
6075   const RawAddress test_address1 = GetTestAddress(1);
6076   int group_id = 5;
6077 
6078   TestSetupRemoteDevices(group_id);
6079   SyncOnMainLoop();
6080 
6081   EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, _)).Times(1);
6082 
6083   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
6084 
6085   SyncOnMainLoop();
6086   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6087   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
6088   Mock::VerifyAndClearExpectations(&mock_state_machine_);
6089   SyncOnMainLoop();
6090 
6091   ASSERT_NE(0lu, streaming_groups.count(group_id));
6092   auto group_inject = streaming_groups.at(group_id);
6093 
6094   // This shall be called once only when first device from the group is disconnecting.
6095   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(1);
6096 
6097   EXPECT_CALL(mock_audio_hal_client_callbacks_, OnConnectionState(ConnectionState::DISCONNECTED, _))
6098           .Times(0);
6099 
6100   // Do not got to IDLE state imidiatelly.
6101   stay_at_releasing_stop_stream = true;
6102 
6103   log::info("First of all disconnect: {}", test_address0);
6104   TriggerDisconnectionFromApp(test_address0);
6105   SyncOnMainLoop();
6106 
6107   log::info("Secondly disconnect: {}", test_address1);
6108   TriggerDisconnectionFromApp(test_address1);
6109   SyncOnMainLoop();
6110 
6111   Mock::VerifyAndClearExpectations(&mock_state_machine_);
6112   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6113 
6114   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6115               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
6116           .Times(1);
6117   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6118               OnConnectionState(ConnectionState::DISCONNECTED, test_address1))
6119           .Times(1);
6120 
6121   do_in_main_thread(base::BindOnce(
6122           [](bluetooth::le_audio::LeAudioGroupStateMachine::Callbacks* cb, int group_id) {
6123             cb->StatusReportCb(group_id, GroupStreamStatus::IDLE);
6124           },
6125           state_machine_callbacks_, group_id));
6126   SyncOnMainLoop();
6127   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6128 }
6129 
TEST_F(UnicastTest,EarbudsTwsStyleStreaming)6130 TEST_F(UnicastTest, EarbudsTwsStyleStreaming) {
6131   const RawAddress test_address0 = GetTestAddress(0);
6132   int group_id = bluetooth::groups::kGroupUnknown;
6133 
6134   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
6135                                 codec_spec_conf::kLeAudioLocationStereo, 0x01, 0x01,
6136                                 codec_spec_caps::kLeAudioSamplingFreq16000Hz, false /*add_csis*/,
6137                                 true /*add_cas*/, true /*add_pacs*/, 2 /*add_asc_cnt*/,
6138                                 1 /*set_size*/, 0 /*rank*/);
6139   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6140               OnConnectionState(ConnectionState::CONNECTED, test_address0))
6141           .Times(1);
6142   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6143               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
6144           .WillOnce(DoAll(SaveArg<1>(&group_id)));
6145 
6146   log::info("Connect device");
6147   ConnectLeAudio(test_address0);
6148   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
6149 
6150   // Expected CIS count on streaming
6151   uint8_t cis_count_out = 2;
6152   uint8_t cis_count_in = 0;
6153 
6154   log::info("Group is getting Active");
6155   // Audio sessions are started only when device gets active
6156   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
6157   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
6158   LeAudioClient::Get()->GroupSetActive(group_id);
6159   SyncOnMainLoop();
6160 
6161   log::info("Start stream");
6162   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
6163 
6164   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6165   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
6166   SyncOnMainLoop();
6167 
6168   log::info("Verify Data transfer on one audio source cis");
6169   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
6170 
6171   log::info("Suspend");
6172   EXPECT_CALL(mock_state_machine_, SuspendStream(_)).Times(1);
6173   LeAudioClient::Get()->GroupSuspend(group_id);
6174   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6175   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
6176 
6177   log::info("Resume");
6178   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
6179   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6180   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
6181 
6182   log::info("Stop");
6183   StopStreaming(group_id);
6184   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6185 
6186   // Release
6187   EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop()).Times(1);
6188   EXPECT_CALL(*mock_codec_manager_,
6189               UpdateActiveUnicastAudioHalClient(mock_le_audio_source_hal_client_,
6190                                                 mock_le_audio_sink_hal_client_, false))
6191           .Times(1);
6192 
6193   EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(1);
6194   EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(1);
6195   LeAudioClient::Get()->GroupSetActive(bluetooth::groups::kGroupUnknown);
6196   SyncOnMainLoop();
6197   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
6198   Mock::VerifyAndClearExpectations(mock_codec_manager_);
6199 }
6200 
TEST_F(UnicastTest,SpeakerFailedConversationalStreaming)6201 TEST_F(UnicastTest, SpeakerFailedConversationalStreaming) {
6202   const RawAddress test_address0 = GetTestAddress(0);
6203   int group_id = bluetooth::groups::kGroupUnknown;
6204 
6205   available_src_context_types_ = 0;
6206   supported_src_context_types_ =
6207           available_src_context_types_ |
6208           types::AudioContexts(types::LeAudioContextType::UNSPECIFIED).value();
6209   available_snk_context_types_ = 0x0004;
6210   supported_snk_context_types_ =
6211           available_snk_context_types_ |
6212           types::AudioContexts(types::LeAudioContextType::UNSPECIFIED).value();
6213 
6214   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo, 0,
6215                                 default_channel_cnt, default_channel_cnt, 0x0004,
6216                                 /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/,
6217                                 true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
6218                                 0 /*rank*/);
6219   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6220               OnConnectionState(ConnectionState::CONNECTED, test_address0))
6221           .Times(1);
6222   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6223               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
6224           .WillOnce(DoAll(SaveArg<1>(&group_id)));
6225 
6226   ConnectLeAudio(test_address0);
6227   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
6228 
6229   // Audio sessions are started only when device gets active
6230   LeAudioClient::Get()->GroupSetActive(group_id);
6231   SyncOnMainLoop();
6232 
6233   /* Nothing to do - expect no crash */
6234 }
6235 
TEST_F(UnicastTest,SpeakerStreaming)6236 TEST_F(UnicastTest, SpeakerStreaming) {
6237   const RawAddress test_address0 = GetTestAddress(0);
6238   int group_id = bluetooth::groups::kGroupUnknown;
6239 
6240   SetSampleDatabaseEarbudsValid(
6241           1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
6242           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
6243           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
6244           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
6245   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6246               OnConnectionState(ConnectionState::CONNECTED, test_address0))
6247           .Times(1);
6248   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6249               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
6250           .WillOnce(DoAll(SaveArg<1>(&group_id)));
6251 
6252   ConnectLeAudio(test_address0);
6253   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
6254 
6255   // Start streaming
6256   uint8_t cis_count_out = 1;
6257   uint8_t cis_count_in = 0;
6258 
6259   // Audio sessions are started only when device gets active
6260   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
6261   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
6262   LeAudioClient::Get()->GroupSetActive(group_id);
6263   SyncOnMainLoop();
6264 
6265   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
6266 
6267   SyncOnMainLoop();
6268   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6269   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
6270 
6271   // Verify Data transfer on one audio source cis
6272   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
6273 
6274   // Suspend
6275   /*TODO Need a way to verify STOP */
6276   LeAudioClient::Get()->GroupSuspend(group_id);
6277   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6278   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
6279 
6280   // Resume
6281   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
6282   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6283   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
6284 
6285   // Stop
6286   StopStreaming(group_id);
6287   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6288 
6289   // Release
6290   EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop()).Times(1);
6291 
6292   EXPECT_CALL(*mock_codec_manager_,
6293               UpdateActiveUnicastAudioHalClient(mock_le_audio_source_hal_client_,
6294                                                 mock_le_audio_sink_hal_client_, false))
6295           .Times(1);
6296 
6297   EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(1);
6298   EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(1);
6299   LeAudioClient::Get()->GroupSetActive(bluetooth::groups::kGroupUnknown);
6300   SyncOnMainLoop();
6301   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
6302   Mock::VerifyAndClearExpectations(mock_codec_manager_);
6303 }
6304 
TEST_F(UnicastTest,SpeakerStreamingNonDefault)6305 TEST_F(UnicastTest, SpeakerStreamingNonDefault) {
6306   const RawAddress test_address0 = GetTestAddress(0);
6307   int group_id = bluetooth::groups::kGroupUnknown;
6308 
6309   /**
6310    * Scenario test steps
6311    * 1. Set group active and stream VOICEASSISTANT
6312    * 2. Suspend group and resume with VOICEASSISTANT
6313    * 3. Stop Stream and make group inactive
6314    * 4. Start stream without setting metadata.
6315    * 5. Verify that UNSPECIFIED context type is used.
6316    */
6317 
6318   available_snk_context_types_ =
6319           (types::LeAudioContextType::VOICEASSISTANTS | types::LeAudioContextType::MEDIA |
6320            types::LeAudioContextType::UNSPECIFIED)
6321                   .value();
6322   supported_snk_context_types_ = available_snk_context_types_;
6323 
6324   SetSampleDatabaseEarbudsValid(
6325           1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
6326           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
6327           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
6328           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
6329   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6330               OnConnectionState(ConnectionState::CONNECTED, test_address0))
6331           .Times(1);
6332   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6333               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
6334           .WillOnce(DoAll(SaveArg<1>(&group_id)));
6335 
6336   ConnectLeAudio(test_address0);
6337   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
6338 
6339   // Start streaming
6340   uint8_t cis_count_out = 1;
6341   uint8_t cis_count_in = 0;
6342 
6343   // Audio sessions are started only when device gets active
6344   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
6345   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
6346   LeAudioClient::Get()->GroupSetActive(group_id);
6347   SyncOnMainLoop();
6348 
6349   StartStreaming(AUDIO_USAGE_ASSISTANT, AUDIO_CONTENT_TYPE_UNKNOWN, group_id);
6350 
6351   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6352   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
6353   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
6354   SyncOnMainLoop();
6355 
6356   // Verify Data transfer on one audio source cis
6357   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
6358 
6359   // Suspend
6360   /*TODO Need a way to verify STOP */
6361   LeAudioClient::Get()->GroupSuspend(group_id);
6362   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6363   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
6364 
6365   // Resume
6366   StartStreaming(AUDIO_USAGE_ASSISTANT, AUDIO_CONTENT_TYPE_UNKNOWN, group_id);
6367   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6368   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
6369 
6370   // Stop
6371   StopStreaming(group_id);
6372   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6373 
6374   // Release
6375   EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop()).Times(1);
6376   EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(1);
6377   EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(1);
6378   LeAudioClient::Get()->GroupSetActive(bluetooth::groups::kGroupUnknown);
6379   SyncOnMainLoop();
6380   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
6381 
6382   /* When session is closed, the hal client mocks are freed - get new ones */
6383   SetUpMockAudioHal();
6384   /* Expect the previous release to clear the old audio session metadata */
6385   LeAudioClient::Get()->GroupSetActive(group_id);
6386   SyncOnMainLoop();
6387   EXPECT_CALL(mock_state_machine_, StartStream(_, types::LeAudioContextType::VOICEASSISTANTS, _, _))
6388           .Times(0);
6389   EXPECT_CALL(mock_state_machine_, StartStream(_, kLeAudioDefaultConfigurationContext, _, _))
6390           .Times(1);
6391   LocalAudioSourceResume();
6392 }
6393 
TEST_F(UnicastTest,TestUnidirectionalGameAndLiveRecording)6394 TEST_F(UnicastTest, TestUnidirectionalGameAndLiveRecording) {
6395   com::android::bluetooth::flags::provider_->le_audio_support_unidirectional_voice_assistant(true);
6396   const RawAddress test_address0 = GetTestAddress(0);
6397   int group_id = bluetooth::groups::kGroupUnknown;
6398 
6399   /**
6400    * Scenario test steps
6401    * 1. Configure group to support GAME only on SINK
6402    * 2. Configure group to support LIVE
6403    * 3. Start recording with LIVE
6404    * 4. Update context type with GAME
6405    * 5. Verify that Configuration did not changed.
6406    */
6407 
6408   available_snk_context_types_ =
6409           (types::LeAudioContextType::GAME | types::LeAudioContextType::MEDIA |
6410            types::LeAudioContextType::UNSPECIFIED | types::LeAudioContextType::LIVE)
6411                   .value();
6412   supported_snk_context_types_ = available_snk_context_types_;
6413 
6414   available_src_context_types_ =
6415           (types::LeAudioContextType::LIVE | types::LeAudioContextType::UNSPECIFIED).value();
6416   supported_src_context_types_ = available_src_context_types_;
6417 
6418   default_channel_cnt = 1;
6419 
6420   SetSampleDatabaseEarbudsValid(
6421           1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
6422           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
6423           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
6424           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
6425   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6426               OnConnectionState(ConnectionState::CONNECTED, test_address0))
6427           .Times(1);
6428   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6429               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
6430           .WillOnce(DoAll(SaveArg<1>(&group_id)));
6431 
6432   types::BidirectionalPair<types::AudioContexts> metadata_contexts = {
6433           .sink = types::AudioContexts(types::LeAudioContextType::LIVE),
6434           .source = types::AudioContexts(types::LeAudioContextType::LIVE)};
6435   EXPECT_CALL(mock_state_machine_,
6436               StartStream(_, types::LeAudioContextType::LIVE, metadata_contexts, _))
6437           .Times(1);
6438 
6439   log::info("Connecting LeAudio to {}", test_address0);
6440   ConnectLeAudio(test_address0);
6441   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
6442 
6443   // Audio sessions are started only when device gets active
6444   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
6445   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
6446 
6447   EXPECT_CALL(*mock_codec_manager_,
6448               UpdateActiveUnicastAudioHalClient(mock_le_audio_source_hal_client_,
6449                                                 mock_le_audio_sink_hal_client_, true))
6450           .Times(1);
6451 
6452   LeAudioClient::Get()->GroupSetActive(group_id);
6453   SyncOnMainLoop();
6454 
6455   UpdateLocalSinkMetadata(AUDIO_SOURCE_MIC);
6456   LocalAudioSinkResume();
6457   SyncOnMainLoop();
6458 
6459   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6460   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
6461   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
6462   Mock::VerifyAndClearExpectations(mock_codec_manager_);
6463   Mock::VerifyAndClearExpectations(&mock_state_machine_);
6464   SyncOnMainLoop();
6465 
6466   // We do expect only unidirectional CIS
6467   uint8_t cis_count_out = 0;
6468   uint8_t cis_count_in = 1;
6469 
6470   // Verify Data transfer on one local audio source cis
6471   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 0, 40);
6472   SyncOnMainLoop();
6473 
6474   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(0);
6475   UpdateLocalSourceMetadata(AUDIO_USAGE_GAME, AUDIO_CONTENT_TYPE_UNKNOWN);
6476   LocalAudioSourceResume();
6477   SyncOnMainLoop();
6478   Mock::VerifyAndClearExpectations(&mock_state_machine_);
6479 }
6480 
TEST_F(UnicastTest,TestUnidirectionalVoiceAssistant_Sink)6481 TEST_F(UnicastTest, TestUnidirectionalVoiceAssistant_Sink) {
6482   com::android::bluetooth::flags::provider_->le_audio_support_unidirectional_voice_assistant(true);
6483   const RawAddress test_address0 = GetTestAddress(0);
6484   int group_id = bluetooth::groups::kGroupUnknown;
6485 
6486   /**
6487    * Scenario test steps
6488    * 1. Configure group to support VOICEASSISTANT only on SINK
6489    * 2. Start stream
6490    * 5. Verify that Unidirectional VOICEASSISTANT has been created
6491    */
6492 
6493   available_snk_context_types_ =
6494           (types::LeAudioContextType::VOICEASSISTANTS | types::LeAudioContextType::MEDIA |
6495            types::LeAudioContextType::UNSPECIFIED)
6496                   .value();
6497   supported_snk_context_types_ = available_snk_context_types_;
6498 
6499   available_src_context_types_ =
6500           (types::LeAudioContextType::LIVE | types::LeAudioContextType::UNSPECIFIED).value();
6501   supported_src_context_types_ = available_src_context_types_;
6502 
6503   SetSampleDatabaseEarbudsValid(
6504           1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
6505           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
6506           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
6507           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
6508   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6509               OnConnectionState(ConnectionState::CONNECTED, test_address0))
6510           .Times(1);
6511   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6512               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
6513           .WillOnce(DoAll(SaveArg<1>(&group_id)));
6514 
6515   types::BidirectionalPair<types::AudioContexts> metadata_contexts = {
6516           .sink = types::AudioContexts(types::LeAudioContextType::VOICEASSISTANTS),
6517           .source = types::AudioContexts()};
6518   EXPECT_CALL(mock_state_machine_,
6519               StartStream(_, types::LeAudioContextType::VOICEASSISTANTS, metadata_contexts, _))
6520           .Times(1);
6521 
6522   log::info("Connecting LeAudio to {}", test_address0);
6523   ConnectLeAudio(test_address0);
6524   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
6525 
6526   // We do expect only unidirectional CIS
6527   uint8_t cis_count_out = 1;
6528   uint8_t cis_count_in = 0;
6529 
6530   // Audio sessions are started only when device gets active
6531   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
6532   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
6533 
6534   EXPECT_CALL(*mock_codec_manager_,
6535               UpdateActiveUnicastAudioHalClient(mock_le_audio_source_hal_client_,
6536                                                 mock_le_audio_sink_hal_client_, true))
6537           .Times(1);
6538 
6539   LeAudioClient::Get()->GroupSetActive(group_id);
6540   SyncOnMainLoop();
6541 
6542   StartStreaming(AUDIO_USAGE_ASSISTANT, AUDIO_CONTENT_TYPE_UNKNOWN, group_id);
6543 
6544   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6545   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
6546   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
6547   Mock::VerifyAndClearExpectations(mock_codec_manager_);
6548   SyncOnMainLoop();
6549 
6550   // Verify Data transfer on one local audio source cis
6551   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
6552   SyncOnMainLoop();
6553 }
6554 
TEST_F(UnicastTest,TestUnidirectionalVoiceAssistant_Source)6555 TEST_F(UnicastTest, TestUnidirectionalVoiceAssistant_Source) {
6556   com::android::bluetooth::flags::provider_->le_audio_support_unidirectional_voice_assistant(true);
6557   const RawAddress test_address0 = GetTestAddress(0);
6558   int group_id = bluetooth::groups::kGroupUnknown;
6559 
6560   /**
6561    * Scenario test steps
6562    * 1. Configure group to support VOICEASSISTANT only on SOURCE
6563    * 2. Start stream
6564    * 5. Verify that uni-direction VOICEASSISTANT has been created
6565    */
6566 
6567   available_snk_context_types_ =
6568           (types::LeAudioContextType::MEDIA | types::LeAudioContextType::UNSPECIFIED).value();
6569   supported_snk_context_types_ = available_snk_context_types_;
6570 
6571   available_src_context_types_ =
6572           (types::LeAudioContextType::VOICEASSISTANTS | types::LeAudioContextType::LIVE |
6573            types::LeAudioContextType::UNSPECIFIED)
6574                   .value();
6575   supported_src_context_types_ = available_src_context_types_;
6576 
6577   SetSampleDatabaseEarbudsValid(
6578           1, test_address0, codec_spec_conf::kLeAudioLocationFrontLeftOfCenter,
6579           codec_spec_conf::kLeAudioLocationFrontLeftOfCenter, default_channel_cnt,
6580           default_channel_cnt, 0x0004,
6581           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
6582           default_ase_cnt /*add_ascs_cnt*/, 2 /*set_size*/, 1 /*rank*/);
6583   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6584               OnConnectionState(ConnectionState::CONNECTED, test_address0))
6585           .Times(1);
6586   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6587               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
6588           .WillOnce(DoAll(SaveArg<1>(&group_id)));
6589 
6590   types::BidirectionalPair<types::AudioContexts> metadata_contexts = {
6591           .sink = types::AudioContexts(),
6592           .source = types::AudioContexts(types::LeAudioContextType::VOICEASSISTANTS)};
6593   EXPECT_CALL(mock_state_machine_,
6594               StartStream(_, types::LeAudioContextType::VOICEASSISTANTS, metadata_contexts, _))
6595           .Times(1);
6596 
6597   log::info("Connecting LeAudio device {}", test_address0);
6598 
6599   ConnectLeAudio(test_address0);
6600   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
6601 
6602   // Expected only unidirectional CIS
6603   uint8_t cis_count_out = 0;
6604   uint8_t cis_count_in = 1;
6605 
6606   // Audio sessions are started only when device gets active
6607   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
6608   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
6609   LeAudioClient::Get()->GroupSetActive(group_id);
6610   SyncOnMainLoop();
6611 
6612   UpdateLocalSinkMetadata(AUDIO_SOURCE_VOICE_RECOGNITION);
6613   LocalAudioSinkResume();
6614 
6615   // Verify Data transfer on one local audio source cis
6616   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
6617 
6618   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6619   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
6620   SyncOnMainLoop();
6621 }
6622 
TEST_F(UnicastTest,SpeakerStreamingAutonomousRelease)6623 TEST_F(UnicastTest, SpeakerStreamingAutonomousRelease) {
6624   const RawAddress test_address0 = GetTestAddress(0);
6625   int group_id = bluetooth::groups::kGroupUnknown;
6626 
6627   SetSampleDatabaseEarbudsValid(
6628           1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
6629           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
6630           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
6631           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
6632   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6633               OnConnectionState(ConnectionState::CONNECTED, test_address0))
6634           .Times(1);
6635   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6636               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
6637           .WillOnce(DoAll(SaveArg<1>(&group_id)));
6638 
6639   ConnectLeAudio(test_address0);
6640   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
6641 
6642   // Start streaming
6643   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
6644   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
6645   LeAudioClient::Get()->GroupSetActive(group_id);
6646   SyncOnMainLoop();
6647 
6648   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
6649 
6650   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6651   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
6652   SyncOnMainLoop();
6653 
6654   // Verify Data transfer on one audio source cis
6655   TestAudioDataTransfer(group_id, 1 /* cis_count_out */, 0 /* cis_count_in */, 1920);
6656 
6657   // Inject the IDLE state as if an autonomous release happened
6658   ASSERT_NE(0lu, streaming_groups.count(group_id));
6659   auto group = streaming_groups.at(group_id);
6660   ASSERT_NE(group, nullptr);
6661   for (LeAudioDevice* device = group->GetFirstDevice(); device != nullptr;
6662        device = group->GetNextDevice(device)) {
6663     for (auto& ase : device->ases_) {
6664       ase.cis_state = types::CisState::IDLE;
6665       ase.data_path_state = types::DataPathState::IDLE;
6666       ase.state = types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE;
6667       InjectCisDisconnected(group_id, ase.cis_conn_hdl);
6668     }
6669   }
6670 
6671   // Verify no Data transfer after the autonomous release
6672   TestAudioDataTransfer(group_id, 0 /* cis_count_out */, 0 /* cis_count_in */, 1920);
6673 }
6674 
TEST_F(UnicastTest,TwoEarbudsStreaming)6675 TEST_F(UnicastTest, TwoEarbudsStreaming) {
6676   uint8_t group_size = 2;
6677   int group_id = 2;
6678 
6679   // Report working CSIS
6680   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
6681   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
6682           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
6683 
6684   // First earbud
6685   const RawAddress test_address0 = GetTestAddress(0);
6686   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
6687   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
6688                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
6689 
6690   // Second earbud
6691   const RawAddress test_address1 = GetTestAddress(1);
6692   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
6693   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
6694                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
6695                     true /*connect_through_csis*/);
6696 
6697   // Start streaming
6698   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
6699   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
6700   LeAudioClient::Get()->GroupSetActive(group_id);
6701   SyncOnMainLoop();
6702 
6703   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
6704 
6705   /* Make sure configurations are non empty */
6706   btle_audio_codec_config_t call_config = {.codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
6707                                            .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_32000HZ,
6708                                            .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
6709                                            .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
6710                                            .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
6711                                            .octets_per_frame = 80};
6712 
6713   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6714               OnAudioGroupCurrentCodecConf(group_id, call_config, call_config))
6715           .Times(1);
6716 
6717   StartStreaming(AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_CONTENT_TYPE_SPEECH, group_id);
6718 
6719   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6720   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
6721   SyncOnMainLoop();
6722 
6723   // Verify Data transfer on two peer sinks and one source
6724   uint8_t cis_count_out = 2;
6725   uint8_t cis_count_in = 2;
6726   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 40);
6727 
6728   // Suspend
6729   LeAudioClient::Get()->GroupSuspend(group_id);
6730   SyncOnMainLoop();
6731 
6732   // Resume
6733   StartStreaming(AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_CONTENT_TYPE_SPEECH, group_id);
6734   SyncOnMainLoop();
6735   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
6736 
6737   // Verify Data transfer still works
6738   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 40);
6739 
6740   ASSERT_NE(0lu, streaming_groups.count(group_id));
6741   auto group = streaming_groups.at(group_id);
6742 
6743   // Stop
6744   StopStreaming(group_id, true);
6745   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6746 
6747   // Check if cache configuration is still present
6748   ASSERT_TRUE(group->GetCachedConfiguration(types::LeAudioContextType::CONVERSATIONAL)
6749                       ->confs.get(le_audio::types::kLeAudioDirectionSink)
6750                       .size());
6751   ASSERT_TRUE(group->GetCachedConfiguration(types::LeAudioContextType::CONVERSATIONAL)
6752                       ->confs.get(le_audio::types::kLeAudioDirectionSource)
6753                       .size());
6754 
6755   // Release
6756   EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop()).Times(1);
6757   EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(1);
6758   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Stop()).Times(1);
6759   EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(1);
6760   LeAudioClient::Get()->GroupSetActive(bluetooth::groups::kGroupUnknown);
6761   SyncOnMainLoop();
6762 
6763   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
6764 
6765   // Setting group inactive, shall not change cached configuration
6766   ASSERT_TRUE(group->GetCachedConfiguration(types::LeAudioContextType::CONVERSATIONAL)
6767                       ->confs.get(le_audio::types::kLeAudioDirectionSink)
6768                       .size());
6769   ASSERT_TRUE(group->GetCachedConfiguration(types::LeAudioContextType::CONVERSATIONAL)
6770                       ->confs.get(le_audio::types::kLeAudioDirectionSource)
6771                       .size());
6772 }
6773 
TEST_F(UnicastTest,TestSetValidSingleOutputPreferredCodecConfig)6774 TEST_F(UnicastTest, TestSetValidSingleOutputPreferredCodecConfig) {
6775   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
6776 
6777   btle_audio_codec_config_t preferred_output_codec_config = {
6778           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
6779           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_24000HZ,
6780           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
6781           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
6782           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
6783           .octets_per_frame = 60};
6784   // We did not set input preferred codec config
6785   btle_audio_codec_config_t empty_input_codec_config;
6786 
6787   int group_id = 2;
6788   TestSetupRemoteDevices(group_id);
6789   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
6790   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6791   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
6792 
6793   ASSERT_EQ(LeAudioClient::Get()->IsUsingPreferredCodecConfig(
6794                     group_id, static_cast<int>(types::LeAudioContextType::MEDIA)),
6795             false);
6796   do_in_main_thread(base::BindOnce(&LeAudioClient::SetCodecConfigPreference,
6797                                    base::Unretained(LeAudioClient::Get()), group_id,
6798                                    empty_input_codec_config, preferred_output_codec_config));
6799   SyncOnMainLoop();
6800   ASSERT_EQ(LeAudioClient::Get()->IsUsingPreferredCodecConfig(
6801                     group_id, static_cast<int>(types::LeAudioContextType::MEDIA)),
6802             true);
6803   // We only set output preferred codec config so bidirectional context would
6804   // use default config
6805   ASSERT_EQ(LeAudioClient::Get()->IsUsingPreferredCodecConfig(
6806                     group_id, static_cast<int>(types::LeAudioContextType::CONVERSATIONAL)),
6807             false);
6808 }
6809 
TEST_F(UnicastTest,TestSetPreferredCodecConfigToNonActiveGroup)6810 TEST_F(UnicastTest, TestSetPreferredCodecConfigToNonActiveGroup) {
6811   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
6812 
6813   int group_id = 2;
6814   TestSetupRemoteDevices(group_id);
6815   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
6816   ASSERT_EQ(LeAudioClient::Get()->IsUsingPreferredCodecConfig(
6817                     group_id, static_cast<int>(types::LeAudioContextType::MEDIA)),
6818             false);
6819 
6820   // Inactivate group 2
6821   LeAudioClient::Get()->GroupSetActive(bluetooth::groups::kGroupUnknown);
6822 
6823   btle_audio_codec_config_t preferred_codec_config = {
6824           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
6825           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_16000HZ,
6826           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
6827           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
6828           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
6829           .octets_per_frame = 40};
6830 
6831   // Re-initialize mock for destroyed hal client
6832   RegisterSourceHalClientMock();
6833   RegisterSinkHalClientMock();
6834 
6835   // Reconfiguration not needed as set preferred config to non active group
6836   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(0);
6837   EXPECT_CALL(*mock_le_audio_source_hal_client_, ReconfigurationComplete()).Times(0);
6838 
6839   do_in_main_thread(base::BindOnce(&LeAudioClient::SetCodecConfigPreference,
6840                                    base::Unretained(LeAudioClient::Get()), group_id,
6841                                    preferred_codec_config, preferred_codec_config));
6842   SyncOnMainLoop();
6843 
6844   ASSERT_EQ(LeAudioClient::Get()->IsUsingPreferredCodecConfig(
6845                     group_id, static_cast<int>(types::LeAudioContextType::MEDIA)),
6846             true);
6847   Mock::VerifyAndClearExpectations(&mock_state_machine_);
6848   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
6849 
6850   // Activate group 2 again
6851   do_in_main_thread(base::BindOnce(&LeAudioClient::GroupSetActive,
6852                                    base::Unretained(LeAudioClient::Get()), group_id));
6853   SyncOnMainLoop();
6854 
6855   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
6856   ASSERT_EQ(LeAudioClient::Get()->IsUsingPreferredCodecConfig(
6857                     group_id, static_cast<int>(types::LeAudioContextType::MEDIA)),
6858             true);
6859 }
6860 
TEST_F(UnicastTest,TwoEarbudsClearPreferenceBeforeMedia)6861 TEST_F(UnicastTest, TwoEarbudsClearPreferenceBeforeMedia) {
6862   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
6863 
6864   int group_id = 2;
6865   TestSetupRemoteDevices(group_id);
6866 
6867   btle_audio_codec_config_t preferred_codec_config_before_media = {.codec_priority = -1};
6868 
6869   bool set_before_media = true;
6870   bool set_while_media = false;
6871   bool is_using_set_before_media_codec_during_media = false;
6872   bool is_using_set_while_media_codec_during_media = false;
6873   // Use legacy codec and should not reconfig while streaming
6874   bool is_reconfig = false;
6875   TestSetCodecPreference(&preferred_codec_config_before_media, nullptr, LeAudioContextType::MEDIA,
6876                          group_id, set_before_media, set_while_media,
6877                          is_using_set_before_media_codec_during_media,
6878                          is_using_set_while_media_codec_during_media, is_reconfig);
6879 }
6880 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceSuccessBeforeMedia)6881 TEST_F(UnicastTest, TwoEarbudsSetPreferenceSuccessBeforeMedia) {
6882   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
6883 
6884   int group_id = 2;
6885   TestSetupRemoteDevices(group_id);
6886 
6887   // This codec can be used by media
6888   btle_audio_codec_config_t preferred_codec_config_before_media = {
6889           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
6890           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_16000HZ,
6891           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
6892           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
6893           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
6894           .octets_per_frame = 40};
6895 
6896   bool set_before_media = true;
6897   bool set_while_media = false;
6898   bool is_using_set_before_media_codec_during_media = true;
6899   bool is_using_set_while_media_codec_during_media = false;
6900   // Use preferred codec and should not reconfig while streaming
6901   bool is_reconfig = false;
6902   TestSetCodecPreference(&preferred_codec_config_before_media, nullptr, LeAudioContextType::MEDIA,
6903                          group_id, set_before_media, set_while_media,
6904                          is_using_set_before_media_codec_during_media,
6905                          is_using_set_while_media_codec_during_media, is_reconfig);
6906 }
6907 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceFailBeforeMedia)6908 TEST_F(UnicastTest, TwoEarbudsSetPreferenceFailBeforeMedia) {
6909   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
6910 
6911   int group_id = 2;
6912   TestSetupRemoteDevices(group_id);
6913 
6914   // This codec can not be used by media
6915   btle_audio_codec_config_t preferred_codec_config_before_media = {
6916           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
6917           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_16000HZ,
6918           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
6919           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
6920           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
6921           .octets_per_frame = 70};
6922 
6923   bool set_before_media = true;
6924   bool set_while_media = false;
6925   bool is_using_set_before_media_codec_during_media = false;
6926   bool is_using_set_while_media_codec_during_media = false;
6927   // Use legacy codec and should not reconfig while streaming
6928   bool is_reconfig = false;
6929   TestSetCodecPreference(&preferred_codec_config_before_media, nullptr, LeAudioContextType::MEDIA,
6930                          group_id, set_before_media, set_while_media,
6931                          is_using_set_before_media_codec_during_media,
6932                          is_using_set_while_media_codec_during_media, is_reconfig);
6933 }
6934 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceSuccessDuringMediaWithReconfig)6935 TEST_F(UnicastTest, TwoEarbudsSetPreferenceSuccessDuringMediaWithReconfig) {
6936   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
6937 
6938   int group_id = 2;
6939   TestSetupRemoteDevices(group_id);
6940 
6941   // This codec can be used by media
6942   btle_audio_codec_config_t preferred_codec_config_during_media = {
6943           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
6944           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_24000HZ,
6945           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
6946           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
6947           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
6948           .octets_per_frame = 60};
6949 
6950   bool set_before_media = false;
6951   bool set_while_media = true;
6952   bool is_using_set_before_media_codec_during_media = false;
6953   bool is_using_set_while_media_codec_during_media = true;
6954   // Should reconfig and use preferred codec while streaming
6955   bool is_reconfig = true;
6956   TestSetCodecPreference(nullptr, &preferred_codec_config_during_media, LeAudioContextType::MEDIA,
6957                          group_id, set_before_media, set_while_media,
6958                          is_using_set_before_media_codec_during_media,
6959                          is_using_set_while_media_codec_during_media, is_reconfig);
6960 }
6961 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceSuccessDuringMediaWithoutReconfig)6962 TEST_F(UnicastTest, TwoEarbudsSetPreferenceSuccessDuringMediaWithoutReconfig) {
6963   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
6964 
6965   int group_id = 2;
6966   TestSetupRemoteDevices(group_id);
6967 
6968   // This codec can be used by media
6969   btle_audio_codec_config_t preferred_codec_config_during_media = {
6970           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
6971           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_48000HZ,
6972           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
6973           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
6974           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
6975           .octets_per_frame = 120};
6976 
6977   bool set_before_media = false;
6978   bool set_while_media = true;
6979   bool is_using_set_before_media_codec_during_media = false;
6980   bool is_using_set_while_media_codec_during_media = true;
6981   // Use preferred codec but not reconfig while streaming since same codec with
6982   // original
6983   bool is_reconfig = false;
6984   TestSetCodecPreference(nullptr, &preferred_codec_config_during_media, LeAudioContextType::MEDIA,
6985                          group_id, set_before_media, set_while_media,
6986                          is_using_set_before_media_codec_during_media,
6987                          is_using_set_while_media_codec_during_media, is_reconfig);
6988 }
6989 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceFailDuringMediaWithoutReconfig)6990 TEST_F(UnicastTest, TwoEarbudsSetPreferenceFailDuringMediaWithoutReconfig) {
6991   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
6992 
6993   int group_id = 2;
6994   TestSetupRemoteDevices(group_id);
6995 
6996   // This codec can not be used by media
6997   btle_audio_codec_config_t preferred_codec_config_during_media = {
6998           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
6999           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_16000HZ,
7000           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7001           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7002           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7003           .octets_per_frame = 70};
7004 
7005   bool set_before_media = false;
7006   bool set_while_media = true;
7007   bool is_using_set_before_media_codec_during_media = false;
7008   bool is_using_set_while_media_codec_during_media = false;
7009   // Use original codec and should not reconfig while streaming
7010   bool is_reconfig = false;
7011   TestSetCodecPreference(nullptr, &preferred_codec_config_during_media, LeAudioContextType::MEDIA,
7012                          group_id, set_before_media, set_while_media,
7013                          is_using_set_before_media_codec_during_media,
7014                          is_using_set_while_media_codec_during_media, is_reconfig);
7015 }
7016 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceSucessBeforeMediaClearPreferenceDuringMediaWithReconfig)7017 TEST_F(UnicastTest,
7018        TwoEarbudsSetPreferenceSucessBeforeMediaClearPreferenceDuringMediaWithReconfig) {
7019   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7020 
7021   int group_id = 2;
7022   TestSetupRemoteDevices(group_id);
7023 
7024   // This codec can be used by media
7025   btle_audio_codec_config_t preferred_codec_config_before_media = {
7026           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7027           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_16000HZ,
7028           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7029           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7030           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7031           .octets_per_frame = 40};
7032   btle_audio_codec_config_t preferred_codec_config_during_media = {.codec_priority = -1};
7033 
7034   bool set_before_media = true;
7035   bool set_while_media = true;
7036   bool is_using_set_before_media_codec_during_media = true;
7037   bool is_using_set_while_media_codec_during_media = false;
7038   // Should reconfig to legacy codec while streaming as we clear preferred codec
7039   bool is_reconfig = true;
7040   TestSetCodecPreference(&preferred_codec_config_before_media, &preferred_codec_config_during_media,
7041                          LeAudioContextType::MEDIA, group_id, set_before_media, set_while_media,
7042                          is_using_set_before_media_codec_during_media,
7043                          is_using_set_while_media_codec_during_media, is_reconfig);
7044 }
7045 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceSucessBeforeMediaSetPreferenceSuccessDuringMediaWithReconfig)7046 TEST_F(UnicastTest,
7047        TwoEarbudsSetPreferenceSucessBeforeMediaSetPreferenceSuccessDuringMediaWithReconfig) {
7048   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7049 
7050   int group_id = 2;
7051   TestSetupRemoteDevices(group_id);
7052 
7053   // This codec can be used by media
7054   btle_audio_codec_config_t preferred_codec_config_before_media = {
7055           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7056           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_16000HZ,
7057           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7058           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7059           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7060           .octets_per_frame = 40};
7061   // This codec can be used by media
7062   btle_audio_codec_config_t preferred_codec_config_during_media = {
7063           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7064           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_24000HZ,
7065           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7066           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7067           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7068           .octets_per_frame = 60};
7069 
7070   bool set_before_media = true;
7071   bool set_while_media = true;
7072   bool is_using_set_before_media_codec_during_media = true;
7073   bool is_using_set_while_media_codec_during_media = true;
7074   // Should reconfig to new preferred codec from old preferred codec while streaming
7075   bool is_reconfig = true;
7076   TestSetCodecPreference(&preferred_codec_config_before_media, &preferred_codec_config_during_media,
7077                          LeAudioContextType::MEDIA, group_id, set_before_media, set_while_media,
7078                          is_using_set_before_media_codec_during_media,
7079                          is_using_set_while_media_codec_during_media, is_reconfig);
7080 }
7081 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceSucessBeforeMediaSetPreferenceSuccessDuringMediaWithoutReconfig)7082 TEST_F(UnicastTest,
7083        TwoEarbudsSetPreferenceSucessBeforeMediaSetPreferenceSuccessDuringMediaWithoutReconfig) {
7084   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7085 
7086   int group_id = 2;
7087   TestSetupRemoteDevices(group_id);
7088 
7089   // This codec can be used by media
7090   btle_audio_codec_config_t preferred_codec_config_before_media = {
7091           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7092           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_16000HZ,
7093           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7094           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7095           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7096           .octets_per_frame = 40};
7097   // This codec can be used by media
7098   btle_audio_codec_config_t preferred_codec_config_during_media = {
7099           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7100           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_16000HZ,
7101           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7102           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7103           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7104           .octets_per_frame = 40};
7105 
7106   bool set_before_media = true;
7107   bool set_while_media = true;
7108   bool is_using_set_before_media_codec_during_media = true;
7109   bool is_using_set_while_media_codec_during_media = true;
7110   // Should not reconfig while streaming because same as previous preferred codec
7111   bool is_reconfig = false;
7112   TestSetCodecPreference(&preferred_codec_config_before_media, &preferred_codec_config_during_media,
7113                          LeAudioContextType::MEDIA, group_id, set_before_media, set_while_media,
7114                          is_using_set_before_media_codec_during_media,
7115                          is_using_set_while_media_codec_during_media, is_reconfig);
7116 }
7117 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceSucessBeforeMediaSetPreferenceFailDuringMediaWithReconfig)7118 TEST_F(UnicastTest,
7119        TwoEarbudsSetPreferenceSucessBeforeMediaSetPreferenceFailDuringMediaWithReconfig) {
7120   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7121 
7122   int group_id = 2;
7123   TestSetupRemoteDevices(group_id);
7124 
7125   // This codec can be used by media
7126   btle_audio_codec_config_t preferred_codec_config_before_media = {
7127           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7128           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_16000HZ,
7129           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7130           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7131           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7132           .octets_per_frame = 40};
7133   // This codec can not be used by media
7134   btle_audio_codec_config_t preferred_codec_config_during_media = {
7135           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7136           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_16000HZ,
7137           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7138           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7139           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7140           .octets_per_frame = 70};
7141 
7142   bool set_before_media = true;
7143   bool set_while_media = true;
7144   bool is_using_set_before_media_codec_during_media = true;
7145   bool is_using_set_while_media_codec_during_media = false;
7146   // Should reconfig to legacy codec while streaming because invalid preferred codec
7147   bool is_reconfig = true;
7148   TestSetCodecPreference(&preferred_codec_config_before_media, &preferred_codec_config_during_media,
7149                          LeAudioContextType::MEDIA, group_id, set_before_media, set_while_media,
7150                          is_using_set_before_media_codec_during_media,
7151                          is_using_set_while_media_codec_during_media, is_reconfig);
7152 }
7153 
TEST_F(UnicastTest,TwoEarbudsClearPreferenceBeforeConv)7154 TEST_F(UnicastTest, TwoEarbudsClearPreferenceBeforeConv) {
7155   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7156 
7157   int group_id = 2;
7158   TestSetupRemoteDevices(group_id);
7159 
7160   btle_audio_codec_config_t preferred_codec_config_before_conv = {.codec_priority = -1};
7161 
7162   // SetInCall is used by GTBS - and only then we can expect CCID to be set.
7163   LeAudioClient::Get()->SetInCall(true);
7164 
7165   bool set_before_conv = true;
7166   bool set_while_conv = false;
7167   bool is_using_set_before_conv_codec_during_conv = false;
7168   bool is_using_set_while_conv_codec_during_conv = false;
7169   // Use legacy codec and should not reconfig while streaming
7170   bool is_reconfig = false;
7171   TestSetCodecPreference(&preferred_codec_config_before_conv, nullptr,
7172                          LeAudioContextType::CONVERSATIONAL, group_id, set_before_conv,
7173                          set_while_conv, is_using_set_before_conv_codec_during_conv,
7174                          is_using_set_while_conv_codec_during_conv, is_reconfig);
7175   LeAudioClient::Get()->SetInCall(false);
7176 }
7177 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceSuccessBeforeConv)7178 TEST_F(UnicastTest, TwoEarbudsSetPreferenceSuccessBeforeConv) {
7179   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7180 
7181   int group_id = 2;
7182   TestSetupRemoteDevices(group_id);
7183 
7184   // This codec can be used by conv
7185   btle_audio_codec_config_t preferred_codec_config_before_conv = {
7186           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7187           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_16000HZ,
7188           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7189           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7190           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7191           .octets_per_frame = 40};
7192 
7193   // SetInCall is used by GTBS - and only then we can expect CCID to be set.
7194   LeAudioClient::Get()->SetInCall(true);
7195 
7196   bool set_before_conv = true;
7197   bool set_while_conv = false;
7198   bool is_using_set_before_conv_codec_during_conv = true;
7199   bool is_using_set_while_conv_codec_during_conv = false;
7200   // Use preferred codec and should not reconfig while streaming
7201   bool is_reconfig = false;
7202   TestSetCodecPreference(&preferred_codec_config_before_conv, nullptr,
7203                          LeAudioContextType::CONVERSATIONAL, group_id, set_before_conv,
7204                          set_while_conv, is_using_set_before_conv_codec_during_conv,
7205                          is_using_set_while_conv_codec_during_conv, is_reconfig);
7206   LeAudioClient::Get()->SetInCall(false);
7207 }
7208 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceFailBeforeConv)7209 TEST_F(UnicastTest, TwoEarbudsSetPreferenceFailBeforeConv) {
7210   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7211 
7212   int group_id = 2;
7213   TestSetupRemoteDevices(group_id);
7214 
7215   // This codec can not be used by conv
7216   btle_audio_codec_config_t preferred_codec_config_before_conv = {
7217           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7218           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_16000HZ,
7219           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7220           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7221           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7222           .octets_per_frame = 70};
7223 
7224   // SetInCall is used by GTBS - and only then we can expect CCID to be set.
7225   LeAudioClient::Get()->SetInCall(true);
7226 
7227   bool set_before_conv = true;
7228   bool set_while_conv = false;
7229   bool is_using_set_before_conv_codec_during_conv = false;
7230   bool is_using_set_while_conv_codec_during_conv = false;
7231   // Use legacy codec and should not reconfig while streaming
7232   bool is_reconfig = false;
7233   TestSetCodecPreference(&preferred_codec_config_before_conv, nullptr,
7234                          LeAudioContextType::CONVERSATIONAL, group_id, set_before_conv,
7235                          set_while_conv, is_using_set_before_conv_codec_during_conv,
7236                          is_using_set_while_conv_codec_during_conv, is_reconfig);
7237   LeAudioClient::Get()->SetInCall(false);
7238 }
7239 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceSuccessDuringConvWithReconfig)7240 TEST_F(UnicastTest, TwoEarbudsSetPreferenceSuccessDuringConvWithReconfig) {
7241   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7242 
7243   int group_id = 2;
7244   TestSetupRemoteDevices(group_id);
7245 
7246   // This codec can be used by conv
7247   btle_audio_codec_config_t preferred_codec_config_during_conv = {
7248           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7249           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_16000HZ,
7250           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7251           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7252           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7253           .octets_per_frame = 40};
7254 
7255   // SetInCall is used by GTBS - and only then we can expect CCID to be set.
7256   LeAudioClient::Get()->SetInCall(true);
7257 
7258   bool set_before_conv = false;
7259   bool set_while_conv = true;
7260   bool is_using_set_before_conv_codec_during_conv = false;
7261   bool is_using_set_while_conv_codec_during_conv = true;
7262   // Should reconfig and use preferred codec while streaming
7263   bool is_reconfig = true;
7264   TestSetCodecPreference(nullptr, &preferred_codec_config_during_conv,
7265                          LeAudioContextType::CONVERSATIONAL, group_id, set_before_conv,
7266                          set_while_conv, is_using_set_before_conv_codec_during_conv,
7267                          is_using_set_while_conv_codec_during_conv, is_reconfig);
7268   LeAudioClient::Get()->SetInCall(false);
7269 }
7270 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceSuccessDuringConvWithoutReconfig)7271 TEST_F(UnicastTest, TwoEarbudsSetPreferenceSuccessDuringConvWithoutReconfig) {
7272   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7273 
7274   int group_id = 2;
7275   TestSetupRemoteDevices(group_id);
7276 
7277   // This codec can be used by conv
7278   btle_audio_codec_config_t preferred_codec_config_during_conv = {
7279           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7280           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_32000HZ,
7281           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7282           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7283           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7284           .octets_per_frame = 80};
7285 
7286   // SetInCall is used by GTBS - and only then we can expect CCID to be set.
7287   LeAudioClient::Get()->SetInCall(true);
7288 
7289   bool set_before_conv = false;
7290   bool set_while_conv = true;
7291   bool is_using_set_before_conv_codec_during_conv = false;
7292   bool is_using_set_while_conv_codec_during_conv = true;
7293   // Use preferred codec but not reconfig while streaming since same codec with
7294   // original
7295   bool is_reconfig = false;
7296   TestSetCodecPreference(nullptr, &preferred_codec_config_during_conv,
7297                          LeAudioContextType::CONVERSATIONAL, group_id, set_before_conv,
7298                          set_while_conv, is_using_set_before_conv_codec_during_conv,
7299                          is_using_set_while_conv_codec_during_conv, is_reconfig);
7300   LeAudioClient::Get()->SetInCall(false);
7301 }
7302 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceFailDuringConvWithoutReconfig)7303 TEST_F(UnicastTest, TwoEarbudsSetPreferenceFailDuringConvWithoutReconfig) {
7304   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7305 
7306   int group_id = 2;
7307   TestSetupRemoteDevices(group_id);
7308 
7309   // This codec can not be used by conv
7310   btle_audio_codec_config_t preferred_codec_config_during_conv = {
7311           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7312           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_16000HZ,
7313           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7314           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7315           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7316           .octets_per_frame = 70};
7317 
7318   // SetInCall is used by GTBS - and only then we can expect CCID to be set.
7319   LeAudioClient::Get()->SetInCall(true);
7320 
7321   bool set_before_conv = false;
7322   bool set_while_conv = true;
7323   bool is_using_set_before_conv_codec_during_conv = false;
7324   bool is_using_set_while_conv_codec_during_conv = false;
7325   // Use original codec and should not reconfig while streaming
7326   bool is_reconfig = false;
7327   TestSetCodecPreference(nullptr, &preferred_codec_config_during_conv,
7328                          LeAudioContextType::CONVERSATIONAL, group_id, set_before_conv,
7329                          set_while_conv, is_using_set_before_conv_codec_during_conv,
7330                          is_using_set_while_conv_codec_during_conv, is_reconfig);
7331   LeAudioClient::Get()->SetInCall(false);
7332 }
7333 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceSucessBeforeConvClearPreferenceDuringConvWithReconfig)7334 TEST_F(UnicastTest, TwoEarbudsSetPreferenceSucessBeforeConvClearPreferenceDuringConvWithReconfig) {
7335   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7336 
7337   int group_id = 2;
7338   TestSetupRemoteDevices(group_id);
7339 
7340   // This codec can be used by conv
7341   btle_audio_codec_config_t preferred_codec_config_before_conv = {
7342           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7343           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_16000HZ,
7344           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7345           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7346           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7347           .octets_per_frame = 40};
7348   btle_audio_codec_config_t preferred_codec_config_during_conv = {.codec_priority = -1};
7349 
7350   // SetInCall is used by GTBS - and only then we can expect CCID to be set.
7351   LeAudioClient::Get()->SetInCall(true);
7352 
7353   bool set_before_conv = true;
7354   bool set_while_conv = true;
7355   bool is_using_set_before_conv_codec_during_conv = true;
7356   bool is_using_set_while_conv_codec_during_conv = false;
7357   // Should reconfig to legacy codec while streaming as we clear preferred codec
7358   bool is_reconfig = true;
7359   TestSetCodecPreference(&preferred_codec_config_before_conv, &preferred_codec_config_during_conv,
7360                          LeAudioContextType::CONVERSATIONAL, group_id, set_before_conv,
7361                          set_while_conv, is_using_set_before_conv_codec_during_conv,
7362                          is_using_set_while_conv_codec_during_conv, is_reconfig);
7363   LeAudioClient::Get()->SetInCall(false);
7364 }
7365 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceSucessBeforeConvSetPreferenceSuccessDuringConvWithReconfig)7366 TEST_F(UnicastTest,
7367        TwoEarbudsSetPreferenceSucessBeforeConvSetPreferenceSuccessDuringConvWithReconfig) {
7368   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7369 
7370   int group_id = 2;
7371   TestSetupRemoteDevices(group_id);
7372 
7373   // This codec can be used by conv
7374   btle_audio_codec_config_t preferred_codec_config_before_conv = {
7375           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7376           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_16000HZ,
7377           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7378           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7379           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7380           .octets_per_frame = 40};
7381   // This codec can be used by conv
7382   btle_audio_codec_config_t preferred_codec_config_during_conv = {
7383           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7384           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_32000HZ,
7385           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7386           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7387           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7388           .octets_per_frame = 80};
7389 
7390   // SetInCall is used by GTBS - and only then we can expect CCID to be set.
7391   LeAudioClient::Get()->SetInCall(true);
7392 
7393   bool set_before_conv = true;
7394   bool set_while_conv = true;
7395   bool is_using_set_before_conv_codec_during_conv = true;
7396   bool is_using_set_while_conv_codec_during_conv = true;
7397   // Should reconfig to new preferred codec from old preferred codec while
7398   // streaming
7399   bool is_reconfig = true;
7400   TestSetCodecPreference(&preferred_codec_config_before_conv, &preferred_codec_config_during_conv,
7401                          LeAudioContextType::CONVERSATIONAL, group_id, set_before_conv,
7402                          set_while_conv, is_using_set_before_conv_codec_during_conv,
7403                          is_using_set_while_conv_codec_during_conv, is_reconfig);
7404   LeAudioClient::Get()->SetInCall(false);
7405 }
7406 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceSucessBeforeConvSetPreferenceSuccessDuringConvWithoutReconfig)7407 TEST_F(UnicastTest,
7408        TwoEarbudsSetPreferenceSucessBeforeConvSetPreferenceSuccessDuringConvWithoutReconfig) {
7409   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7410 
7411   int group_id = 2;
7412   TestSetupRemoteDevices(group_id);
7413 
7414   // This codec can be used by conv
7415   btle_audio_codec_config_t preferred_codec_config_before_conv = {
7416           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7417           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_16000HZ,
7418           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7419           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7420           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7421           .octets_per_frame = 40};
7422   // This codec can be used by conv
7423   btle_audio_codec_config_t preferred_codec_config_during_conv = {
7424           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7425           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_16000HZ,
7426           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7427           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7428           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7429           .octets_per_frame = 40};
7430 
7431   // SetInCall is used by GTBS - and only then we can expect CCID to be set.
7432   LeAudioClient::Get()->SetInCall(true);
7433 
7434   bool set_before_conv = true;
7435   bool set_while_conv = true;
7436   bool is_using_set_before_conv_codec_during_conv = true;
7437   bool is_using_set_while_conv_codec_during_conv = true;
7438   // Should not reconfig while streaming because same as previous preferred
7439   // codec
7440   bool is_reconfig = false;
7441   TestSetCodecPreference(&preferred_codec_config_before_conv, &preferred_codec_config_during_conv,
7442                          LeAudioContextType::CONVERSATIONAL, group_id, set_before_conv,
7443                          set_while_conv, is_using_set_before_conv_codec_during_conv,
7444                          is_using_set_while_conv_codec_during_conv, is_reconfig);
7445   LeAudioClient::Get()->SetInCall(false);
7446 }
7447 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceSucessBeforeConvSetPreferenceFailDuringConvWithReconfig)7448 TEST_F(UnicastTest,
7449        TwoEarbudsSetPreferenceSucessBeforeConvSetPreferenceFailDuringConvWithReconfig) {
7450   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7451 
7452   int group_id = 2;
7453   TestSetupRemoteDevices(group_id);
7454 
7455   // This codec can be used by conv
7456   btle_audio_codec_config_t preferred_codec_config_before_conv = {
7457           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7458           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_16000HZ,
7459           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7460           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7461           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7462           .octets_per_frame = 40};
7463   // This codec can not be used by conv
7464   btle_audio_codec_config_t preferred_codec_config_during_conv = {
7465           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7466           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_16000HZ,
7467           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7468           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7469           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7470           .octets_per_frame = 70};
7471 
7472   // SetInCall is used by GTBS - and only then we can expect CCID to be set.
7473   LeAudioClient::Get()->SetInCall(true);
7474 
7475   bool set_before_conv = true;
7476   bool set_while_conv = true;
7477   bool is_using_set_before_conv_codec_during_conv = true;
7478   bool is_using_set_while_conv_codec_during_conv = false;
7479   // Should reconfig to legacy codec while streaming because invalid preferred
7480   // codec
7481   bool is_reconfig = true;
7482   TestSetCodecPreference(&preferred_codec_config_before_conv, &preferred_codec_config_during_conv,
7483                          LeAudioContextType::CONVERSATIONAL, group_id, set_before_conv,
7484                          set_while_conv, is_using_set_before_conv_codec_during_conv,
7485                          is_using_set_while_conv_codec_during_conv, is_reconfig);
7486   LeAudioClient::Get()->SetInCall(false);
7487 }
7488 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceWhenIdleForBothMediaAndConv)7489 TEST_F(UnicastTest, TwoEarbudsSetPreferenceWhenIdleForBothMediaAndConv) {
7490   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7491 
7492   int group_id = 2;
7493   TestSetupRemoteDevices(group_id);
7494 
7495   // This codec can be used by media and conv
7496   btle_audio_codec_config_t preferred_codec_config_before_media = {
7497           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7498           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_16000HZ,
7499           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7500           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7501           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7502           .octets_per_frame = 40};
7503 
7504   bool set_before_media = true;
7505   bool set_while_media = false;
7506   bool is_using_set_before_media_codec_during_media = true;
7507   bool is_using_set_while_media_codec_during_media = false;
7508   bool is_reconfig = false;
7509   TestSetCodecPreference(&preferred_codec_config_before_media, nullptr, LeAudioContextType::MEDIA,
7510                          group_id, set_before_media, set_while_media,
7511                          is_using_set_before_media_codec_during_media,
7512                          is_using_set_while_media_codec_during_media, is_reconfig);
7513 
7514   // simulate suspend timeout passed, alarm executing
7515   fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
7516   SyncOnMainLoop();
7517 
7518   // SetInCall is used by GTBS - and only then we can expect CCID to be set.
7519   LeAudioClient::Get()->SetInCall(true);
7520 
7521   bool set_before_conv = false;
7522   bool set_while_conv = false;
7523   bool is_using_set_before_conv_codec_during_conv = true;
7524   bool is_using_set_while_conv_codec_during_conv = false;
7525   is_reconfig = false;
7526   TestSetCodecPreference(nullptr, nullptr, LeAudioContextType::CONVERSATIONAL, group_id,
7527                          set_before_conv, set_while_conv,
7528                          is_using_set_before_conv_codec_during_conv,
7529                          is_using_set_while_conv_codec_during_conv, is_reconfig);
7530   LeAudioClient::Get()->SetInCall(false);
7531 
7532   // should use preferred codec when switching back to media
7533   ASSERT_EQ(LeAudioClient::Get()->IsUsingPreferredCodecConfig(
7534                     group_id, static_cast<int>(types::LeAudioContextType::MEDIA)),
7535             true);
7536 }
7537 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceWhenIdleForMediaNotForConv)7538 TEST_F(UnicastTest, TwoEarbudsSetPreferenceWhenIdleForMediaNotForConv) {
7539   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7540 
7541   int group_id = 2;
7542   TestSetupRemoteDevices(group_id);
7543 
7544   // This codec can be used by media but not by conv
7545   btle_audio_codec_config_t preferred_codec_config_before_media = {
7546           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7547           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_24000HZ,
7548           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7549           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7550           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7551           .octets_per_frame = 60};
7552 
7553   bool set_before_media = true;
7554   bool set_while_media = false;
7555   bool is_using_set_before_media_codec_during_media = true;
7556   bool is_using_set_while_media_codec_during_media = false;
7557   bool is_reconfig = false;
7558   TestSetCodecPreference(&preferred_codec_config_before_media, nullptr, LeAudioContextType::MEDIA,
7559                          group_id, set_before_media, set_while_media,
7560                          is_using_set_before_media_codec_during_media,
7561                          is_using_set_while_media_codec_during_media, is_reconfig);
7562 
7563   // simulate suspend timeout passed, alarm executing
7564   fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
7565   SyncOnMainLoop();
7566 
7567   // SetInCall is used by GTBS - and only then we can expect CCID to be set.
7568   LeAudioClient::Get()->SetInCall(true);
7569 
7570   bool set_before_conv = false;
7571   bool set_while_conv = false;
7572   bool is_using_set_before_conv_codec_during_conv = false;
7573   bool is_using_set_while_conv_codec_during_conv = false;
7574   is_reconfig = false;
7575   TestSetCodecPreference(nullptr, nullptr, LeAudioContextType::CONVERSATIONAL, group_id,
7576                          set_before_conv, set_while_conv,
7577                          is_using_set_before_conv_codec_during_conv,
7578                          is_using_set_while_conv_codec_during_conv, is_reconfig);
7579   LeAudioClient::Get()->SetInCall(false);
7580 
7581   // should use preferred codec when switching back to media
7582   ASSERT_EQ(LeAudioClient::Get()->IsUsingPreferredCodecConfig(
7583                     group_id, static_cast<int>(types::LeAudioContextType::MEDIA)),
7584             true);
7585 }
7586 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceWhenIdleNotForMediaForConv)7587 TEST_F(UnicastTest, TwoEarbudsSetPreferenceWhenIdleNotForMediaForConv) {
7588   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7589 
7590   int group_id = 2;
7591   TestSetupRemoteDevices(group_id);
7592 
7593   // This codec can not be used by media but by conv
7594   btle_audio_codec_config_t preferred_codec_config_before_media = {
7595           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7596           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_32000HZ,
7597           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7598           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7599           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7600           .octets_per_frame = 80};
7601 
7602   bool set_before_media = true;
7603   bool set_while_media = false;
7604   bool is_using_set_before_media_codec_during_media = false;
7605   bool is_using_set_while_media_codec_during_media = false;
7606   bool is_reconfig = false;
7607   TestSetCodecPreference(&preferred_codec_config_before_media, nullptr, LeAudioContextType::MEDIA,
7608                          group_id, set_before_media, set_while_media,
7609                          is_using_set_before_media_codec_during_media,
7610                          is_using_set_while_media_codec_during_media, is_reconfig);
7611 
7612   // simulate suspend timeout passed, alarm executing
7613   fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
7614   SyncOnMainLoop();
7615 
7616   // SetInCall is used by GTBS - and only then we can expect CCID to be set.
7617   LeAudioClient::Get()->SetInCall(true);
7618 
7619   bool set_before_conv = false;
7620   bool set_while_conv = false;
7621   bool is_using_set_before_conv_codec_during_conv = true;
7622   bool is_using_set_while_conv_codec_during_conv = false;
7623   is_reconfig = false;
7624   TestSetCodecPreference(nullptr, nullptr, LeAudioContextType::CONVERSATIONAL, group_id,
7625                          set_before_conv, set_while_conv,
7626                          is_using_set_before_conv_codec_during_conv,
7627                          is_using_set_while_conv_codec_during_conv, is_reconfig);
7628   LeAudioClient::Get()->SetInCall(false);
7629 
7630   // should use legacy codec when switching back to media
7631   ASSERT_EQ(LeAudioClient::Get()->IsUsingPreferredCodecConfig(
7632                     group_id, static_cast<int>(types::LeAudioContextType::MEDIA)),
7633             false);
7634 }
7635 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceWhenIdleNotForBothMediaAndConv)7636 TEST_F(UnicastTest, TwoEarbudsSetPreferenceWhenIdleNotForBothMediaAndConv) {
7637   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7638 
7639   int group_id = 2;
7640   TestSetupRemoteDevices(group_id);
7641 
7642   // This codec can not be used by media and conv
7643   btle_audio_codec_config_t preferred_codec_config_before_media = {
7644           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7645           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_24000HZ,
7646           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7647           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7648           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7649           .octets_per_frame = 10};
7650 
7651   bool set_before_media = true;
7652   bool set_while_media = false;
7653   bool is_using_set_before_media_codec_during_media = false;
7654   bool is_using_set_while_media_codec_during_media = false;
7655   bool is_reconfig = false;
7656   TestSetCodecPreference(&preferred_codec_config_before_media, nullptr, LeAudioContextType::MEDIA,
7657                          group_id, set_before_media, set_while_media,
7658                          is_using_set_before_media_codec_during_media,
7659                          is_using_set_while_media_codec_during_media, is_reconfig);
7660 
7661   // simulate suspend timeout passed, alarm executing
7662   fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
7663   SyncOnMainLoop();
7664 
7665   // SetInCall is used by GTBS - and only then we can expect CCID to be set.
7666   LeAudioClient::Get()->SetInCall(true);
7667 
7668   bool set_before_conv = false;
7669   bool set_while_conv = false;
7670   bool is_using_set_before_conv_codec_during_conv = false;
7671   bool is_using_set_while_conv_codec_during_conv = false;
7672   is_reconfig = false;
7673   TestSetCodecPreference(nullptr, nullptr, LeAudioContextType::CONVERSATIONAL, group_id,
7674                          set_before_conv, set_while_conv,
7675                          is_using_set_before_conv_codec_during_conv,
7676                          is_using_set_while_conv_codec_during_conv, is_reconfig);
7677   LeAudioClient::Get()->SetInCall(false);
7678 
7679   // should use legacy codec when switching back to media
7680   ASSERT_EQ(LeAudioClient::Get()->IsUsingPreferredCodecConfig(
7681                     group_id, static_cast<int>(types::LeAudioContextType::MEDIA)),
7682             false);
7683 }
7684 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceWhenMediaForBothMediaAndConv)7685 TEST_F(UnicastTest, TwoEarbudsSetPreferenceWhenMediaForBothMediaAndConv) {
7686   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7687 
7688   int group_id = 2;
7689   TestSetupRemoteDevices(group_id);
7690 
7691   // This codec can be used by media and conv
7692   btle_audio_codec_config_t preferred_codec_config_during_media = {
7693           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7694           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_16000HZ,
7695           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7696           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7697           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7698           .octets_per_frame = 40};
7699 
7700   bool set_before_media = false;
7701   bool set_while_media = true;
7702   bool is_using_set_before_media_codec_during_media = false;
7703   bool is_using_set_while_media_codec_during_media = true;
7704   // should use preferred codec and reconfig
7705   bool is_reconfig = true;
7706   TestSetCodecPreference(nullptr, &preferred_codec_config_during_media, LeAudioContextType::MEDIA,
7707                          group_id, set_before_media, set_while_media,
7708                          is_using_set_before_media_codec_during_media,
7709                          is_using_set_while_media_codec_during_media, is_reconfig);
7710 
7711   log::info("simulate suspend timeout passed, alarm executing");
7712   fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
7713   SyncOnMainLoop();
7714 
7715   log::info("SetInCall is used by GTBS - and only then we can expect CCID to be set.");
7716   LeAudioClient::Get()->SetInCall(true);
7717 
7718   bool set_before_conv = false;
7719   bool set_while_conv = false;
7720   bool is_using_set_before_conv_codec_during_conv = true;
7721   bool is_using_set_while_conv_codec_during_conv = false;
7722   is_reconfig = false;
7723   TestSetCodecPreference(nullptr, nullptr, LeAudioContextType::CONVERSATIONAL, group_id,
7724                          set_before_conv, set_while_conv,
7725                          is_using_set_before_conv_codec_during_conv,
7726                          is_using_set_while_conv_codec_during_conv, is_reconfig);
7727   LeAudioClient::Get()->SetInCall(false);
7728 
7729   log::info("should use preferred codec when switching back to media");
7730   ASSERT_EQ(LeAudioClient::Get()->IsUsingPreferredCodecConfig(
7731                     group_id, static_cast<int>(types::LeAudioContextType::MEDIA)),
7732             true);
7733 }
7734 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceWhenMediaForMediaNotForConv)7735 TEST_F(UnicastTest, TwoEarbudsSetPreferenceWhenMediaForMediaNotForConv) {
7736   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7737 
7738   int group_id = 2;
7739   TestSetupRemoteDevices(group_id);
7740 
7741   // This codec can be used by media but not by conv
7742   btle_audio_codec_config_t preferred_codec_config_during_media = {
7743           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7744           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_24000HZ,
7745           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7746           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7747           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7748           .octets_per_frame = 60};
7749 
7750   bool set_before_media = false;
7751   bool set_while_media = true;
7752   bool is_using_set_before_media_codec_during_media = false;
7753   bool is_using_set_while_media_codec_during_media = true;
7754   // should use preferred codec and reconfig
7755   bool is_reconfig = true;
7756   TestSetCodecPreference(nullptr, &preferred_codec_config_during_media, LeAudioContextType::MEDIA,
7757                          group_id, set_before_media, set_while_media,
7758                          is_using_set_before_media_codec_during_media,
7759                          is_using_set_while_media_codec_during_media, is_reconfig);
7760 
7761   // simulate suspend timeout passed, alarm executing
7762   fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
7763   SyncOnMainLoop();
7764 
7765   // SetInCall is used by GTBS - and only then we can expect CCID to be set.
7766   LeAudioClient::Get()->SetInCall(true);
7767 
7768   bool set_before_conv = false;
7769   bool set_while_conv = false;
7770   bool is_using_set_before_conv_codec_during_conv = false;
7771   bool is_using_set_while_conv_codec_during_conv = false;
7772   is_reconfig = false;
7773   TestSetCodecPreference(nullptr, nullptr, LeAudioContextType::CONVERSATIONAL, group_id,
7774                          set_before_conv, set_while_conv,
7775                          is_using_set_before_conv_codec_during_conv,
7776                          is_using_set_while_conv_codec_during_conv, is_reconfig);
7777   LeAudioClient::Get()->SetInCall(false);
7778 
7779   // should use preferred codec when switching back to media
7780   ASSERT_EQ(LeAudioClient::Get()->IsUsingPreferredCodecConfig(
7781                     group_id, static_cast<int>(types::LeAudioContextType::MEDIA)),
7782             true);
7783 }
7784 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceWhenMediaNotForMediaForConv)7785 TEST_F(UnicastTest, TwoEarbudsSetPreferenceWhenMediaNotForMediaForConv) {
7786   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7787 
7788   int group_id = 2;
7789   TestSetupRemoteDevices(group_id);
7790 
7791   // This codec can not be used by media and but by conv
7792   btle_audio_codec_config_t preferred_codec_config_during_media = {
7793           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7794           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_32000HZ,
7795           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7796           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7797           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7798           .octets_per_frame = 80};
7799 
7800   bool set_before_media = false;
7801   bool set_while_media = true;
7802   bool is_using_set_before_media_codec_during_media = false;
7803   bool is_using_set_while_media_codec_during_media = false;
7804   // should use legacy codec
7805   bool is_reconfig = false;
7806   TestSetCodecPreference(nullptr, &preferred_codec_config_during_media, LeAudioContextType::MEDIA,
7807                          group_id, set_before_media, set_while_media,
7808                          is_using_set_before_media_codec_during_media,
7809                          is_using_set_while_media_codec_during_media, is_reconfig);
7810 
7811   // simulate suspend timeout passed, alarm executing
7812   fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
7813   SyncOnMainLoop();
7814 
7815   // SetInCall is used by GTBS - and only then we can expect CCID to be set.
7816   LeAudioClient::Get()->SetInCall(true);
7817 
7818   bool set_before_conv = false;
7819   bool set_while_conv = false;
7820   bool is_using_set_before_conv_codec_during_conv = true;
7821   bool is_using_set_while_conv_codec_during_conv = false;
7822   is_reconfig = false;
7823   TestSetCodecPreference(nullptr, nullptr, LeAudioContextType::CONVERSATIONAL, group_id,
7824                          set_before_conv, set_while_conv,
7825                          is_using_set_before_conv_codec_during_conv,
7826                          is_using_set_while_conv_codec_during_conv, is_reconfig);
7827   LeAudioClient::Get()->SetInCall(false);
7828 
7829   // should use legacy codec when switching back to media
7830   ASSERT_EQ(LeAudioClient::Get()->IsUsingPreferredCodecConfig(
7831                     group_id, static_cast<int>(types::LeAudioContextType::MEDIA)),
7832             false);
7833 }
7834 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceWhenMediaNotForBothMediaAndConv)7835 TEST_F(UnicastTest, TwoEarbudsSetPreferenceWhenMediaNotForBothMediaAndConv) {
7836   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7837 
7838   int group_id = 2;
7839   TestSetupRemoteDevices(group_id);
7840 
7841   // This codec can not be used by media and conv
7842   btle_audio_codec_config_t preferred_codec_config_during_media = {
7843           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7844           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_24000HZ,
7845           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7846           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7847           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7848           .octets_per_frame = 70};
7849 
7850   bool set_before_media = false;
7851   bool set_while_media = true;
7852   bool is_using_set_before_media_codec_during_media = false;
7853   bool is_using_set_while_media_codec_during_media = false;
7854   // should use legacy codec
7855   bool is_reconfig = false;
7856   TestSetCodecPreference(nullptr, &preferred_codec_config_during_media, LeAudioContextType::MEDIA,
7857                          group_id, set_before_media, set_while_media,
7858                          is_using_set_before_media_codec_during_media,
7859                          is_using_set_while_media_codec_during_media, is_reconfig);
7860 
7861   // simulate suspend timeout passed, alarm executing
7862   fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
7863   SyncOnMainLoop();
7864 
7865   // SetInCall is used by GTBS - and only then we can expect CCID to be set.
7866   LeAudioClient::Get()->SetInCall(true);
7867 
7868   bool set_before_conv = false;
7869   bool set_while_conv = false;
7870   bool is_using_set_before_conv_codec_during_conv = false;
7871   bool is_using_set_while_conv_codec_during_conv = false;
7872   is_reconfig = false;
7873   TestSetCodecPreference(nullptr, nullptr, LeAudioContextType::CONVERSATIONAL, group_id,
7874                          set_before_conv, set_while_conv,
7875                          is_using_set_before_conv_codec_during_conv,
7876                          is_using_set_while_conv_codec_during_conv, is_reconfig);
7877   LeAudioClient::Get()->SetInCall(false);
7878 
7879   // should use legacy codec when switching back to media
7880   ASSERT_EQ(LeAudioClient::Get()->IsUsingPreferredCodecConfig(
7881                     group_id, static_cast<int>(types::LeAudioContextType::MEDIA)),
7882             false);
7883 }
7884 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceWhenConvForBothMediaAndConv)7885 TEST_F(UnicastTest, TwoEarbudsSetPreferenceWhenConvForBothMediaAndConv) {
7886   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7887 
7888   int group_id = 2;
7889   TestSetupRemoteDevices(group_id);
7890 
7891   bool set_before_media = false;
7892   bool set_while_media = false;
7893   bool is_using_set_before_media_codec_during_media = false;
7894   bool is_using_set_while_media_codec_during_media = false;
7895   bool is_reconfig = false;
7896   TestSetCodecPreference(nullptr, nullptr, LeAudioContextType::MEDIA, group_id, set_before_media,
7897                          set_while_media, is_using_set_before_media_codec_during_media,
7898                          is_using_set_while_media_codec_during_media, is_reconfig);
7899 
7900   // simulate suspend timeout passed, alarm executing
7901   fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
7902   SyncOnMainLoop();
7903 
7904   // This codec can be used by media and conv
7905   btle_audio_codec_config_t preferred_codec_config_during_conv = {
7906           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7907           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_16000HZ,
7908           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7909           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7910           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7911           .octets_per_frame = 40};
7912 
7913   // SetInCall is used by GTBS - and only then we can expect CCID to be set.
7914   LeAudioClient::Get()->SetInCall(true);
7915 
7916   bool set_before_conv = false;
7917   bool set_while_conv = true;
7918   bool is_using_set_before_conv_codec_during_conv = false;
7919   bool is_using_set_while_conv_codec_during_conv = true;
7920   // should use preferred codec and reconfig
7921   is_reconfig = true;
7922   TestSetCodecPreference(nullptr, &preferred_codec_config_during_conv,
7923                          LeAudioContextType::CONVERSATIONAL, group_id, set_before_conv,
7924                          set_while_conv, is_using_set_before_conv_codec_during_conv,
7925                          is_using_set_while_conv_codec_during_conv, is_reconfig);
7926   LeAudioClient::Get()->SetInCall(false);
7927 
7928   // should use preferred codec when switching back to media
7929   ASSERT_EQ(LeAudioClient::Get()->IsUsingPreferredCodecConfig(
7930                     group_id, static_cast<int>(types::LeAudioContextType::MEDIA)),
7931             true);
7932 }
7933 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceWhenConvForMediaNotForConv)7934 TEST_F(UnicastTest, TwoEarbudsSetPreferenceWhenConvForMediaNotForConv) {
7935   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7936 
7937   int group_id = 2;
7938   TestSetupRemoteDevices(group_id);
7939 
7940   bool set_before_media = false;
7941   bool set_while_media = false;
7942   bool is_using_set_before_media_codec_during_media = false;
7943   bool is_using_set_while_media_codec_during_media = false;
7944   bool is_reconfig = false;
7945   TestSetCodecPreference(nullptr, nullptr, LeAudioContextType::MEDIA, group_id, set_before_media,
7946                          set_while_media, is_using_set_before_media_codec_during_media,
7947                          is_using_set_while_media_codec_during_media, is_reconfig);
7948 
7949   // simulate suspend timeout passed, alarm executing
7950   fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
7951   SyncOnMainLoop();
7952 
7953   // This codec can be used by media but not by conv
7954   btle_audio_codec_config_t preferred_codec_config_during_conv = {
7955           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7956           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_24000HZ,
7957           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7958           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7959           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7960           .octets_per_frame = 60};
7961 
7962   // SetInCall is used by GTBS - and only then we can expect CCID to be set.
7963   LeAudioClient::Get()->SetInCall(true);
7964 
7965   bool set_before_conv = false;
7966   bool set_while_conv = true;
7967   bool is_using_set_before_conv_codec_during_conv = false;
7968   bool is_using_set_while_conv_codec_during_conv = false;
7969   // should use legacy codec
7970   is_reconfig = false;
7971   TestSetCodecPreference(nullptr, &preferred_codec_config_during_conv,
7972                          LeAudioContextType::CONVERSATIONAL, group_id, set_before_conv,
7973                          set_while_conv, is_using_set_before_conv_codec_during_conv,
7974                          is_using_set_while_conv_codec_during_conv, is_reconfig);
7975   LeAudioClient::Get()->SetInCall(false);
7976 
7977   // should use preferred codec when switching back to media
7978   ASSERT_EQ(LeAudioClient::Get()->IsUsingPreferredCodecConfig(
7979                     group_id, static_cast<int>(types::LeAudioContextType::MEDIA)),
7980             true);
7981 }
7982 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceWhenConvNotForMediaForConv)7983 TEST_F(UnicastTest, TwoEarbudsSetPreferenceWhenConvNotForMediaForConv) {
7984   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7985 
7986   int group_id = 2;
7987   TestSetupRemoteDevices(group_id);
7988 
7989   bool set_before_media = false;
7990   bool set_while_media = false;
7991   bool is_using_set_before_media_codec_during_media = false;
7992   bool is_using_set_while_media_codec_during_media = false;
7993   bool is_reconfig = false;
7994   TestSetCodecPreference(nullptr, nullptr, LeAudioContextType::MEDIA, group_id, set_before_media,
7995                          set_while_media, is_using_set_before_media_codec_during_media,
7996                          is_using_set_while_media_codec_during_media, is_reconfig);
7997 
7998   // simulate suspend timeout passed, alarm executing
7999   fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
8000   SyncOnMainLoop();
8001 
8002   // This codec can not be used by media but by conv
8003   btle_audio_codec_config_t preferred_codec_config_during_conv = {
8004           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
8005           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_32000HZ,
8006           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
8007           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
8008           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
8009           .octets_per_frame = 80};
8010 
8011   // SetInCall is used by GTBS - and only then we can expect CCID to be set.
8012   LeAudioClient::Get()->SetInCall(true);
8013 
8014   bool set_before_conv = false;
8015   bool set_while_conv = true;
8016   bool is_using_set_before_conv_codec_during_conv = false;
8017   bool is_using_set_while_conv_codec_during_conv = true;
8018   // should use preferred codec but not reconfig
8019   is_reconfig = false;
8020   TestSetCodecPreference(nullptr, &preferred_codec_config_during_conv,
8021                          LeAudioContextType::CONVERSATIONAL, group_id, set_before_conv,
8022                          set_while_conv, is_using_set_before_conv_codec_during_conv,
8023                          is_using_set_while_conv_codec_during_conv, is_reconfig);
8024   LeAudioClient::Get()->SetInCall(false);
8025 
8026   // should use legacy codec when switching back to media
8027   ASSERT_EQ(LeAudioClient::Get()->IsUsingPreferredCodecConfig(
8028                     group_id, static_cast<int>(types::LeAudioContextType::MEDIA)),
8029             false);
8030 }
8031 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceWhenConvNotForBothMediaAndConv)8032 TEST_F(UnicastTest, TwoEarbudsSetPreferenceWhenConvNotForBothMediaAndConv) {
8033   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
8034 
8035   int group_id = 2;
8036   TestSetupRemoteDevices(group_id);
8037 
8038   bool set_before_media = false;
8039   bool set_while_media = false;
8040   bool is_using_set_before_media_codec_during_media = false;
8041   bool is_using_set_while_media_codec_during_media = false;
8042   bool is_reconfig = false;
8043   TestSetCodecPreference(nullptr, nullptr, LeAudioContextType::MEDIA, group_id, set_before_media,
8044                          set_while_media, is_using_set_before_media_codec_during_media,
8045                          is_using_set_while_media_codec_during_media, is_reconfig);
8046 
8047   // simulate suspend timeout passed, alarm executing
8048   fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
8049   SyncOnMainLoop();
8050 
8051   // This codec can not be used by media and conv
8052   btle_audio_codec_config_t preferred_codec_config_during_conv = {
8053           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
8054           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_24000HZ,
8055           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
8056           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
8057           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
8058           .octets_per_frame = 70};
8059 
8060   // SetInCall is used by GTBS - and only then we can expect CCID to be set.
8061   LeAudioClient::Get()->SetInCall(true);
8062 
8063   bool set_before_conv = false;
8064   bool set_while_conv = true;
8065   bool is_using_set_before_conv_codec_during_conv = false;
8066   bool is_using_set_while_conv_codec_during_conv = false;
8067   // should use legacy codec
8068   is_reconfig = false;
8069   TestSetCodecPreference(nullptr, &preferred_codec_config_during_conv,
8070                          LeAudioContextType::CONVERSATIONAL, group_id, set_before_conv,
8071                          set_while_conv, is_using_set_before_conv_codec_during_conv,
8072                          is_using_set_while_conv_codec_during_conv, is_reconfig);
8073   LeAudioClient::Get()->SetInCall(false);
8074 
8075   // should use legacy codec when switching back to media
8076   ASSERT_EQ(LeAudioClient::Get()->IsUsingPreferredCodecConfig(
8077                     group_id, static_cast<int>(types::LeAudioContextType::MEDIA)),
8078             false);
8079 }
8080 
TEST_F(UnicastTest,StreamingVxAospSampleSound)8081 TEST_F(UnicastTest, StreamingVxAospSampleSound) {
8082   uint8_t group_size = 2;
8083   int group_id = 2;
8084 
8085   /* Test to verify that tag VX_AOSP_SAMPLESOUND is always mapped to
8086    * LeAudioContextType::SOUNDEFFECTS
8087    */
8088 
8089   // Report working CSIS
8090   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
8091 
8092   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
8093           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
8094 
8095   // First earbud
8096   const RawAddress test_address0 = GetTestAddress(0);
8097   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
8098   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
8099                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
8100 
8101   // Second earbud
8102   const RawAddress test_address1 = GetTestAddress(1);
8103   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
8104   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
8105                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
8106                     true /*connect_through_csis*/);
8107 
8108   // Start streaming
8109   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
8110   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
8111   LeAudioClient::Get()->GroupSetActive(group_id);
8112   SyncOnMainLoop();
8113 
8114   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
8115 
8116   // Set a test TAG
8117   char test_tag[] = "TEST_TAG2;VX_AOSP_SAMPLESOUND;TEST_TAG1";
8118 
8119   test_tags_ptr_ = test_tag;
8120 
8121   auto initial_context = types::LeAudioContextType::SOUNDEFFECTS;
8122   types::BidirectionalPair<std::vector<uint8_t>> ccids = {.sink = {}, .source = {}};
8123   EXPECT_CALL(mock_state_machine_, StartStream(_, initial_context, _, ccids)).Times(1);
8124   StartStreaming(AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_CONTENT_TYPE_SPEECH, group_id);
8125 
8126   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
8127   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
8128   SyncOnMainLoop();
8129 
8130   // Verify Data transfer on two peer sinks and one source
8131   uint8_t cis_count_out = 2;
8132   uint8_t cis_count_in = 0;
8133   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 0);
8134 }
8135 
TEST_F(UnicastTest,UpdateActiveAudioConfigForLocalSinkSource)8136 TEST_F(UnicastTest, UpdateActiveAudioConfigForLocalSinkSource) {
8137   uint8_t group_size = 2;
8138   int group_id = 2;
8139 
8140   // Report working CSIS
8141   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
8142 
8143   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
8144           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
8145 
8146   // First earbud
8147   const RawAddress test_address0 = GetTestAddress(0);
8148   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
8149   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
8150                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
8151 
8152   // Second earbud
8153   const RawAddress test_address1 = GetTestAddress(1);
8154   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
8155   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
8156                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
8157                     true /*connect_through_csis*/);
8158 
8159   // Set group as active
8160   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
8161   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
8162   LeAudioClient::Get()->GroupSetActive(group_id);
8163   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
8164 
8165   // Start streaming
8166   EXPECT_CALL(*mock_le_audio_sink_hal_client_, UpdateAudioConfigToHal(_)).Times(1);
8167   EXPECT_CALL(*mock_le_audio_source_hal_client_, UpdateAudioConfigToHal(_)).Times(1);
8168   EXPECT_CALL(*mock_codec_manager_, UpdateActiveAudioConfig(_, _, _))
8169           .Times(1)
8170           .WillOnce([](const types::BidirectionalPair<stream_parameters>& /*stream_params*/,
8171                        types::BidirectionalPair<uint16_t> delays_ms,
8172                        std::function<void(const offload_config& config, uint8_t direction)>
8173                                update_receiver) {
8174             bluetooth::le_audio::offload_config unicast_cfg;
8175             if (delays_ms.sink != 0) {
8176               update_receiver(unicast_cfg, bluetooth::le_audio::types::kLeAudioDirectionSink);
8177             }
8178             if (delays_ms.source != 0) {
8179               update_receiver(unicast_cfg, bluetooth::le_audio::types::kLeAudioDirectionSource);
8180             }
8181           });
8182   StartStreaming(AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_CONTENT_TYPE_SPEECH, group_id);
8183 
8184   SyncOnMainLoop();
8185   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
8186   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
8187   Mock::VerifyAndClearExpectations(&mock_codec_manager_);
8188 
8189   // Verify Data transfer on two peer sinks and two sources
8190   uint8_t cis_count_out = 2;
8191   uint8_t cis_count_in = 2;
8192   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 40);
8193 
8194   // Suspend
8195   LeAudioClient::Get()->GroupSuspend(group_id);
8196   SyncOnMainLoop();
8197 }
8198 
TEST_F(UnicastTest,UpdateActiveAudioConfigForLocalSource)8199 TEST_F(UnicastTest, UpdateActiveAudioConfigForLocalSource) {
8200   uint8_t group_size = 2;
8201   int group_id = 2;
8202 
8203   // Report working CSIS
8204   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
8205 
8206   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
8207           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
8208 
8209   // First earbud
8210   const RawAddress test_address0 = GetTestAddress(0);
8211   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
8212   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
8213                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
8214 
8215   // Second earbud
8216   const RawAddress test_address1 = GetTestAddress(1);
8217   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
8218   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
8219                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
8220                     true /*connect_through_csis*/);
8221 
8222   // Set group as active
8223   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
8224   LeAudioClient::Get()->GroupSetActive(group_id);
8225   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
8226 
8227   // Start streaming
8228   EXPECT_CALL(*mock_le_audio_source_hal_client_, UpdateAudioConfigToHal(_)).Times(1);
8229   EXPECT_CALL(*mock_le_audio_sink_hal_client_, UpdateAudioConfigToHal(_)).Times(0);
8230   EXPECT_CALL(*mock_codec_manager_, UpdateActiveAudioConfig(_, _, _))
8231           .Times(1)
8232           .WillOnce([](const types::BidirectionalPair<stream_parameters>& /*stream_params*/,
8233                        types::BidirectionalPair<uint16_t> delays_ms,
8234                        std::function<void(const offload_config& config, uint8_t direction)>
8235                                update_receiver) {
8236             bluetooth::le_audio::offload_config unicast_cfg;
8237             if (delays_ms.sink != 0) {
8238               update_receiver(unicast_cfg, bluetooth::le_audio::types::kLeAudioDirectionSink);
8239             }
8240             if (delays_ms.source != 0) {
8241               update_receiver(unicast_cfg, bluetooth::le_audio::types::kLeAudioDirectionSource);
8242             }
8243           });
8244   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
8245 
8246   SyncOnMainLoop();
8247   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
8248   Mock::VerifyAndClearExpectations(&mock_codec_manager_);
8249 
8250   // Verify Data transfer on two peer sinks and no source
8251   uint8_t cis_count_out = 2;
8252   uint8_t cis_count_in = 0;
8253   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 40);
8254 
8255   // Suspend
8256   LeAudioClient::Get()->GroupSuspend(group_id);
8257   SyncOnMainLoop();
8258 }
8259 
TEST_F(UnicastTest,TwoEarbudsStreamingContextSwitchNoReconfigure)8260 TEST_F(UnicastTest, TwoEarbudsStreamingContextSwitchNoReconfigure) {
8261   uint8_t group_size = 2;
8262   int group_id = 2;
8263 
8264   // Report working CSIS
8265   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
8266 
8267   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
8268           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
8269 
8270   // First earbud
8271   const RawAddress test_address0 = GetTestAddress(0);
8272   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
8273   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
8274                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
8275 
8276   // Second earbud
8277   const RawAddress test_address1 = GetTestAddress(1);
8278   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
8279   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
8280                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
8281                     true /*connect_through_csis*/);
8282 
8283   // Start streaming
8284   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
8285   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
8286   LeAudioClient::Get()->GroupSetActive(group_id);
8287   SyncOnMainLoop();
8288   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
8289 
8290   // Start streaming with new metadata, there was no previous stream so start
8291   // with this new configuration
8292   auto initial_context = types::LeAudioContextType::NOTIFICATIONS;
8293   types::BidirectionalPair<types::AudioContexts> contexts = {
8294           .sink = types::AudioContexts(initial_context), .source = types::AudioContexts()};
8295   EXPECT_CALL(mock_state_machine_, StartStream(_, initial_context, contexts, _)).Times(1);
8296 
8297   StartStreaming(AUDIO_USAGE_NOTIFICATION, AUDIO_CONTENT_TYPE_UNKNOWN, group_id);
8298 
8299   SyncOnMainLoop();
8300   Mock::VerifyAndClearExpectations(&mock_state_machine_);
8301   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
8302   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
8303 
8304   // Do a metadata content switch to ALERTS but stay on previous configuration
8305   EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(0);
8306   EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop).Times(0);
8307   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start).Times(0);
8308   contexts = {.sink = types::AudioContexts(types::LeAudioContextType::ALERTS),
8309               .source = types::AudioContexts()};
8310   EXPECT_CALL(mock_state_machine_, StartStream(_, initial_context, contexts, _)).Times(1);
8311   UpdateLocalSourceMetadata(AUDIO_USAGE_ALARM, AUDIO_CONTENT_TYPE_UNKNOWN);
8312 
8313   SyncOnMainLoop();
8314   Mock::VerifyAndClearExpectations(&mock_state_machine_);
8315   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
8316   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
8317 
8318   // Do a metadata content switch to EMERGENCY but stay on previous
8319   // configuration
8320   EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(0);
8321   EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop).Times(0);
8322   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start).Times(0);
8323 
8324   contexts = {.sink = types::AudioContexts(types::LeAudioContextType::EMERGENCYALARM),
8325               .source = types::AudioContexts()};
8326   EXPECT_CALL(mock_state_machine_, StartStream(_, initial_context, contexts, _)).Times(1);
8327   UpdateLocalSourceMetadata(AUDIO_USAGE_EMERGENCY, AUDIO_CONTENT_TYPE_UNKNOWN);
8328 
8329   SyncOnMainLoop();
8330   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
8331   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
8332 
8333   // Do a metadata content switch to INSTRUCTIONAL but stay on previous
8334   // configuration
8335   EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(0);
8336   EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop).Times(0);
8337   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start).Times(0);
8338   contexts = {.sink = types::AudioContexts(types::LeAudioContextType::INSTRUCTIONAL),
8339               .source = types::AudioContexts()};
8340   EXPECT_CALL(mock_state_machine_, StartStream(_, initial_context, contexts, _)).Times(1);
8341   UpdateLocalSourceMetadata(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE, AUDIO_CONTENT_TYPE_UNKNOWN);
8342 
8343   SyncOnMainLoop();
8344   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
8345   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
8346 }
8347 
TEST_F(UnicastTest,TwoEarbudsStopConversational_StartStreamSonification)8348 TEST_F(UnicastTest, TwoEarbudsStopConversational_StartStreamSonification) {
8349   uint8_t group_size = 2;
8350   int group_id = 2;
8351 
8352   // Report working CSIS
8353   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
8354 
8355   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
8356           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
8357 
8358   // First earbud
8359   const RawAddress test_address0 = GetTestAddress(0);
8360   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
8361   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
8362                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
8363 
8364   // Second earbud
8365   const RawAddress test_address1 = GetTestAddress(1);
8366   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
8367   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
8368                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
8369                     true /*connect_through_csis*/);
8370 
8371   // Start streaming
8372   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
8373   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
8374   LeAudioClient::Get()->GroupSetActive(group_id);
8375   SyncOnMainLoop();
8376   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
8377 
8378   // Start streaming with CONVERSATIONAL, there was no previous stream so start
8379   // with this new configuration
8380   auto initial_context = types::LeAudioContextType::CONVERSATIONAL;
8381   types::BidirectionalPair<types::AudioContexts> contexts = {
8382           .sink = types::AudioContexts(initial_context),
8383           .source = types::AudioContexts(initial_context)};
8384   EXPECT_CALL(mock_state_machine_, StartStream(_, initial_context, contexts, _)).Times(1);
8385 
8386   StartStreaming(AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_CONTENT_TYPE_SPEECH, group_id);
8387 
8388   SyncOnMainLoop();
8389   Mock::VerifyAndClearExpectations(&mock_state_machine_);
8390   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
8391   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
8392 
8393   // Stop the stream but KEEP cis UP
8394   StopStreaming(group_id, true);
8395   SyncOnMainLoop();
8396   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
8397 
8398   types::BidirectionalPair<types::AudioContexts> reconfigure_contexts = {
8399           .sink = types::AudioContexts(types::LeAudioContextType::ALERTS),
8400           .source = types::AudioContexts()};
8401 
8402   EXPECT_CALL(mock_state_machine_, StartStream(_, initial_context, reconfigure_contexts, _))
8403           .Times(1);
8404 
8405   // Change context type but expect configuration to by as previous
8406   StartStreaming(AUDIO_USAGE_ALARM, AUDIO_CONTENT_TYPE_UNKNOWN, group_id);
8407 
8408   SyncOnMainLoop();
8409   Mock::VerifyAndClearExpectations(&mock_state_machine_);
8410 
8411   // Stop the stream and drop CISes
8412   StopStreaming(group_id, true);
8413   SyncOnMainLoop();
8414   // simulate suspend timeout passed, alarm executing
8415   fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
8416   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
8417 
8418   auto reconfigure_context = types::LeAudioContextType::ALERTS;
8419 
8420   EXPECT_CALL(mock_state_machine_, StartStream(_, reconfigure_context, reconfigure_contexts, _))
8421           .Times(1);
8422 
8423   // Update metadata
8424   StartStreaming(AUDIO_USAGE_ALARM, AUDIO_CONTENT_TYPE_UNKNOWN, group_id);
8425   SyncOnMainLoop();
8426   Mock::VerifyAndClearExpectations(&mock_state_machine_);
8427 }
8428 
TEST_F(UnicastTest,TwoEarbudsStreamingContextSwitchReconfigure)8429 TEST_F(UnicastTest, TwoEarbudsStreamingContextSwitchReconfigure) {
8430   // TODO(b/352686917). Remove the test when flag will be removing
8431   com::android::bluetooth::flags::provider_->leaudio_speed_up_reconfiguration_between_call(false);
8432 
8433   uint8_t group_size = 2;
8434   int group_id = 2;
8435 
8436   // Report working CSIS
8437   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
8438 
8439   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
8440           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
8441 
8442   // First earbud
8443   const RawAddress test_address0 = GetTestAddress(0);
8444   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
8445   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
8446                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
8447 
8448   // Second earbud
8449   const RawAddress test_address1 = GetTestAddress(1);
8450   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
8451   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
8452                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
8453                     true /*connect_through_csis*/);
8454 
8455   constexpr int gmcs_ccid = 1;
8456   constexpr int gtbs_ccid = 2;
8457 
8458   // Start streaming MEDIA
8459   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
8460   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
8461   LeAudioClient::Get()->SetCcidInformation(gmcs_ccid, 4 /* Media */);
8462   LeAudioClient::Get()->SetCcidInformation(gtbs_ccid, 2 /* Phone */);
8463   LeAudioClient::Get()->GroupSetActive(group_id);
8464   SyncOnMainLoop();
8465 
8466   types::BidirectionalPair<std::vector<uint8_t>> ccids = {.sink = {gmcs_ccid}, .source = {}};
8467   EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, ccids)).Times(1);
8468   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
8469 
8470   SyncOnMainLoop();
8471   Mock::VerifyAndClearExpectations(&mock_state_machine_);
8472   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
8473   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
8474 
8475   // Verify Data transfer on two peer sinks
8476   uint8_t cis_count_out = 2;
8477   uint8_t cis_count_in = 0;
8478   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
8479 
8480   // Stop
8481   StopStreaming(group_id);
8482   // simulate suspend timeout passed, alarm executing
8483   fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
8484   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
8485 
8486   log::info("SetInCall is used by GTBS - and only then we can expect CCID to be set.");
8487   LeAudioClient::Get()->SetInCall(true);
8488 
8489   // Conversational is a bidirectional scenario so expect GTBS CCID
8490   // in the metadata for both directions. Can be called twice when one
8491   // direction resume after the other and metadata is updated.
8492   ccids = {.sink = {gtbs_ccid}, .source = {gtbs_ccid}};
8493   EXPECT_CALL(mock_state_machine_,
8494               StartStream(_, types::LeAudioContextType::CONVERSATIONAL, _, ccids))
8495           .Times(AtLeast(1));
8496   StartStreaming(AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_CONTENT_TYPE_SPEECH, group_id);
8497 
8498   SyncOnMainLoop();
8499   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
8500   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
8501 
8502   // Verify Data transfer on two peer sinks and one source
8503   cis_count_out = 2;
8504   cis_count_in = 2;
8505   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 40);
8506 
8507   log::info("End call");
8508   LeAudioClient::Get()->SetInCall(false);
8509   // Stop
8510   StopStreaming(group_id, true);
8511 
8512   log::info("Switch back to MEDIA");
8513   ccids = {.sink = {gmcs_ccid}, .source = {}};
8514   types::BidirectionalPair<types::AudioContexts> contexts = {
8515           .sink = types::AudioContexts(types::LeAudioContextType::MEDIA),
8516           .source = types::AudioContexts()};
8517   EXPECT_CALL(mock_state_machine_,
8518               ConfigureStream(_, bluetooth::le_audio::types::LeAudioContextType::MEDIA, contexts,
8519                               ccids, _))
8520           .Times(1);
8521   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id, AUDIO_SOURCE_INVALID, true);
8522 
8523   SyncOnMainLoop();
8524   Mock::VerifyAndClearExpectations(&mock_state_machine_);
8525   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
8526   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
8527 }
8528 
TEST_F(UnicastTest,TwoEarbudsStreamingContextSwitchReconfigure_SpeedUpReconfigFlagEnabled)8529 TEST_F(UnicastTest, TwoEarbudsStreamingContextSwitchReconfigure_SpeedUpReconfigFlagEnabled) {
8530   com::android::bluetooth::flags::provider_->leaudio_speed_up_reconfiguration_between_call(true);
8531 
8532   uint8_t group_size = 2;
8533   int group_id = 2;
8534 
8535   // Report working CSIS
8536   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
8537 
8538   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
8539           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
8540 
8541   // First earbud
8542   const RawAddress test_address0 = GetTestAddress(0);
8543   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
8544   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
8545                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
8546 
8547   // Second earbud
8548   const RawAddress test_address1 = GetTestAddress(1);
8549   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
8550   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
8551                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
8552                     true /*connect_through_csis*/);
8553 
8554   constexpr int gmcs_ccid = 1;
8555   constexpr int gtbs_ccid = 2;
8556 
8557   log::info("Start streaming MEDIA");
8558   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
8559   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
8560   LeAudioClient::Get()->SetCcidInformation(gmcs_ccid, 4 /* Media */);
8561   LeAudioClient::Get()->SetCcidInformation(gtbs_ccid, 2 /* Phone */);
8562   LeAudioClient::Get()->GroupSetActive(group_id);
8563   SyncOnMainLoop();
8564 
8565   types::BidirectionalPair<std::vector<uint8_t>> ccids = {.sink = {gmcs_ccid}, .source = {}};
8566   EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, ccids)).Times(1);
8567   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
8568 
8569   SyncOnMainLoop();
8570   Mock::VerifyAndClearExpectations(&mock_state_machine_);
8571   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
8572   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
8573 
8574   // Verify Data transfer on two peer sinks
8575   uint8_t cis_count_out = 2;
8576   uint8_t cis_count_in = 0;
8577   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
8578 
8579   log::info("Simulate incoming call");
8580 
8581   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(1);
8582   Expectation reconfigure =
8583           EXPECT_CALL(*mock_le_audio_source_hal_client_, SuspendedForReconfiguration()).Times(1);
8584   EXPECT_CALL(*mock_le_audio_source_hal_client_, CancelStreamingRequest()).Times(1);
8585   EXPECT_CALL(*mock_le_audio_source_hal_client_, ReconfigurationComplete())
8586           .Times(1)
8587           .After(reconfigure);
8588   EXPECT_CALL(mock_state_machine_, ConfigureStream(_, _, _, _, _)).Times(1);
8589   // SetInCall is used by GTBS - and only then we can expect CCID to be set.
8590   LeAudioClient::Get()->SetInCall(true);
8591   SyncOnMainLoop();
8592   Mock::VerifyAndClearExpectations(&mock_state_machine_);
8593   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
8594 
8595   // Conversational is a bidirectional scenario so expect GTBS CCID
8596   // in the metadata for both directions. Can be called twice when one
8597   // direction resume after the other and metadata is updated.
8598   ccids = {.sink = {gtbs_ccid}, .source = {gtbs_ccid}};
8599   EXPECT_CALL(mock_state_machine_,
8600               StartStream(_, types::LeAudioContextType::CONVERSATIONAL, _, ccids))
8601           .Times(AtLeast(1));
8602   StartStreaming(AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_CONTENT_TYPE_SPEECH, group_id);
8603 
8604   SyncOnMainLoop();
8605   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
8606   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
8607 
8608   // Verify Data transfer on two peer sinks and one source
8609   cis_count_out = 2;
8610   cis_count_in = 2;
8611   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 40);
8612 
8613   Mock::VerifyAndClearExpectations(&mock_state_machine_);
8614 
8615   // Stop stream will be called by SetInCall
8616   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(1);
8617   reconfigure =
8618           EXPECT_CALL(*mock_le_audio_source_hal_client_, SuspendedForReconfiguration()).Times(1);
8619   EXPECT_CALL(*mock_le_audio_source_hal_client_, CancelStreamingRequest()).Times(1);
8620   EXPECT_CALL(*mock_le_audio_source_hal_client_, ReconfigurationComplete())
8621           .Times(1)
8622           .After(reconfigure);
8623   EXPECT_CALL(mock_state_machine_, ConfigureStream(_, _, _, _, _)).Times(1);
8624 
8625   LeAudioClient::Get()->SetInCall(false);
8626   SyncOnMainLoop();
8627 
8628   Mock::VerifyAndClearExpectations(&mock_state_machine_);
8629   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
8630 
8631   log::info("Switch back to media");
8632 
8633   ccids = {.sink = {gmcs_ccid}, .source = {}};
8634   types::BidirectionalPair<types::AudioContexts> contexts = {
8635           .sink = types::AudioContexts(types::LeAudioContextType::MEDIA),
8636           .source = types::AudioContexts()};
8637   EXPECT_CALL(mock_state_machine_,
8638               ConfigureStream(_, bluetooth::le_audio::types::LeAudioContextType::MEDIA, contexts,
8639                               ccids, _))
8640           .Times(0);
8641   EXPECT_CALL(
8642           mock_state_machine_,
8643           StartStream(_, bluetooth::le_audio::types::LeAudioContextType::MEDIA, contexts, ccids))
8644           .Times(1);
8645   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id, AUDIO_SOURCE_INVALID,
8646                  false);
8647 
8648   SyncOnMainLoop();
8649   Mock::VerifyAndClearExpectations(&mock_state_machine_);
8650   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
8651   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
8652 }
8653 
TEST_F(UnicastTest,TwoEarbudsVoipStreamingVerifyMetadataUpdate)8654 TEST_F(UnicastTest, TwoEarbudsVoipStreamingVerifyMetadataUpdate) {
8655   uint8_t group_size = 2;
8656   int group_id = 2;
8657 
8658   /*
8659    * Scenario
8660    * 1. Configure stream for the VOIP
8661    * 2. Verify CONVERSATIONAL metadata and context is used.
8662    * 3. Resume LocalSink
8663    * 4. Make sure there is no change of the metadata and context
8664    */
8665 
8666   // Report working CSIS
8667   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
8668 
8669   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
8670           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
8671 
8672   // First earbud
8673   const RawAddress test_address0 = GetTestAddress(0);
8674   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
8675   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
8676                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
8677 
8678   // Second earbud
8679   const RawAddress test_address1 = GetTestAddress(1);
8680   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
8681   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
8682                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
8683                     true /*connect_through_csis*/);
8684 
8685   constexpr int gtbs_ccid = 2;
8686 
8687   LeAudioClient::Get()->SetCcidInformation(gtbs_ccid, 2 /* Phone */);
8688   LeAudioClient::Get()->GroupSetActive(group_id);
8689   SyncOnMainLoop();
8690 
8691   // VOIP not using Telecom API has no ccids.
8692   types::BidirectionalPair<std::vector<uint8_t>> ccids = {.sink = {}, .source = {}};
8693   EXPECT_CALL(mock_state_machine_,
8694               StartStream(_, types::LeAudioContextType::CONVERSATIONAL, _, ccids))
8695           .Times(AtLeast(1));
8696 
8697   UpdateLocalSourceMetadata(AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_CONTENT_TYPE_SPEECH);
8698   UpdateLocalSinkMetadata(AUDIO_SOURCE_MIC);
8699 
8700   LocalAudioSourceResume();
8701   SyncOnMainLoop();
8702   Mock::VerifyAndClearExpectations(&mock_state_machine_);
8703 
8704   SyncOnMainLoop();
8705   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
8706   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
8707 
8708   // Verify Data transfer are sending. The LocalSink is not yet resumed.
8709   uint8_t cis_count_out = 2;
8710   uint8_t cis_count_in = 0;
8711   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 0);
8712 
8713   types::BidirectionalPair<types::AudioContexts> contexts = {
8714           .sink = types::AudioContexts(types::LeAudioContextType::CONVERSATIONAL),
8715           .source = types::AudioContexts(types::LeAudioContextType::CONVERSATIONAL)};
8716   EXPECT_CALL(mock_state_machine_,
8717               StartStream(_, types::LeAudioContextType::CONVERSATIONAL, contexts, ccids))
8718           .Times(AtLeast(1));
8719 
8720   LocalAudioSinkResume();
8721   SyncOnMainLoop();
8722   Mock::VerifyAndClearExpectations(&mock_state_machine_);
8723 }
8724 
TEST_F(UnicastTest,TwoReconfigureAndVerifyEnableContextType)8725 TEST_F(UnicastTest, TwoReconfigureAndVerifyEnableContextType) {
8726   uint8_t group_size = 2;
8727   int group_id = 2;
8728 
8729   /* Scenario
8730    * 1. Earbuds streaming MEDIA
8731    * 2. Reconfigure to VOIP
8732    * 3. Check if Metadata in Enable command are set to CONVERSATIONAL
8733    */
8734 
8735   // Report working CSIS
8736   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
8737 
8738   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
8739           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
8740 
8741   // First earbud
8742   const RawAddress test_address0 = GetTestAddress(0);
8743   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
8744   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
8745                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
8746 
8747   // Second earbud
8748   const RawAddress test_address1 = GetTestAddress(1);
8749   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
8750   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
8751                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
8752                     true /*connect_through_csis*/);
8753 
8754   constexpr int gmcs_ccid = 1;
8755   constexpr int gtbs_ccid = 2;
8756 
8757   // Start streaming MEDIA
8758   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
8759   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
8760   LeAudioClient::Get()->SetCcidInformation(gmcs_ccid, 4 /* Media */);
8761   LeAudioClient::Get()->SetCcidInformation(gtbs_ccid, 2 /* Phone */);
8762   LeAudioClient::Get()->GroupSetActive(group_id);
8763   SyncOnMainLoop();
8764 
8765   // Update metadata on local audio sink
8766   UpdateLocalSinkMetadata(AUDIO_SOURCE_MIC);
8767 
8768   types::BidirectionalPair<std::vector<uint8_t>> ccids = {.sink = {gmcs_ccid}, .source = {}};
8769   EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, ccids)).Times(1);
8770   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
8771 
8772   SyncOnMainLoop();
8773   Mock::VerifyAndClearExpectations(&mock_state_machine_);
8774   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
8775   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
8776 
8777   // Verify Data transfer on two peer sinks
8778   uint8_t cis_count_out = 2;
8779   uint8_t cis_count_in = 0;
8780   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
8781 
8782   // Conversational is a bidirectional scenario so expect GTBS CCID
8783   // in the metadata for both directions. Can be called twice when one
8784   // direction resume after the other and metadata is updated.
8785   ccids = {.sink = {gtbs_ccid}, .source = {gtbs_ccid}};
8786   types::BidirectionalPair<types::AudioContexts> conversiational_contexts = {
8787           .sink = types::AudioContexts(types::LeAudioContextType::CONVERSATIONAL),
8788           .source = types::AudioContexts(types::LeAudioContextType::CONVERSATIONAL)};
8789 
8790   EXPECT_CALL(mock_state_machine_,
8791               ConfigureStream(_, types::LeAudioContextType::CONVERSATIONAL, _, _, _))
8792           .Times(AtLeast(1));
8793 
8794   // Update metadata and resume
8795   UpdateLocalSourceMetadata(AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_CONTENT_TYPE_SPEECH, true);
8796   SyncOnMainLoop();
8797 
8798   Mock::VerifyAndClearExpectations(&mock_state_machine_);
8799   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
8800   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
8801 
8802   EXPECT_CALL(mock_state_machine_, StartStream(_, types::LeAudioContextType::CONVERSATIONAL,
8803                                                conversiational_contexts, ccids))
8804           .Times(AtLeast(1));
8805 
8806   LeAudioClient::Get()->SetInCall(true);
8807 
8808   LocalAudioSourceResume(true);
8809   SyncOnMainLoop();
8810 
8811   Mock::VerifyAndClearExpectations(&mock_state_machine_);
8812 }
8813 
TEST_F(UnicastTest,TwoEarbuds2ndLateConnect)8814 TEST_F(UnicastTest, TwoEarbuds2ndLateConnect) {
8815   uint8_t group_size = 2;
8816   int group_id = 2;
8817 
8818   // Report working CSIS
8819   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
8820 
8821   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
8822           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
8823 
8824   const RawAddress test_address0 = GetTestAddress(0);
8825   const RawAddress test_address1 = GetTestAddress(1);
8826 
8827   // First earbud
8828   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
8829                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
8830 
8831   // Start streaming
8832   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
8833   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
8834   LeAudioClient::Get()->GroupSetActive(group_id);
8835   SyncOnMainLoop();
8836 
8837   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
8838 
8839   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
8840   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
8841   SyncOnMainLoop();
8842 
8843   // Expect one iso channel to be fed with data
8844   uint8_t cis_count_out = 1;
8845   uint8_t cis_count_in = 0;
8846   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
8847 
8848   // Second earbud connects during stream
8849   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
8850                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
8851                     true /*connect_through_csis*/);
8852 
8853   cis_count_out = 2;
8854   cis_count_in = 0;
8855 
8856   /* The above will trigger reconfiguration. After that Audio Hal action
8857    * is needed to restart the stream */
8858   LocalAudioSourceResume();
8859 
8860   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
8861 }
8862 
TEST_F(UnicastTest,LateStreamConnectBasedOnContextType)8863 TEST_F(UnicastTest, LateStreamConnectBasedOnContextType) {
8864   uint8_t group_size = 2;
8865   int group_id = 2;
8866 
8867   /* Scenario
8868    * 1. Two devices A and B are connect. Device A has all available context
8869    * types, Device B has no available context types.
8870    * 2. Stream creation to Device A has been started
8871    * 3. Device B notified us with new available Context Types - while A is not
8872    * yet streaming
8873    * 4. Make sure AttachToStream was called for Device B
8874    */
8875 
8876   // Report working CSIS
8877   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
8878 
8879   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
8880           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
8881 
8882   const RawAddress test_address0 = GetTestAddress(0);
8883   const RawAddress test_address1 = GetTestAddress(1);
8884 
8885   // First earbud connects
8886   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
8887                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
8888 
8889   // Second earbud connects
8890   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
8891                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
8892                     true /*connect_through_csis*/);
8893 
8894   // Start streaming
8895   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
8896   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
8897   LeAudioClient::Get()->GroupSetActive(group_id);
8898   SyncOnMainLoop();
8899 
8900   /* Simulate available context type being cleared */
8901   InjectAvailableContextTypes(test_address1, 2, types::AudioContexts(0), types::AudioContexts(0));
8902 
8903   // Block streaming state
8904   stay_at_qos_config_in_start_stream = true;
8905 
8906   UpdateLocalSourceMetadata(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC);
8907   LocalAudioSourceResume(false);
8908 
8909   SyncOnMainLoop();
8910   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
8911 
8912   InjectAvailableContextTypes(test_address1, 2, types::kLeAudioContextAllRemoteSinkOnly,
8913                               types::AudioContexts(0), false);
8914 
8915   // Now simulate group is finally streaming
8916   auto group = streaming_groups.at(group_id);
8917   do_in_main_thread(base::BindOnce(
8918           [](int group_id,
8919              bluetooth::le_audio::LeAudioGroupStateMachine::Callbacks* state_machine_callbacks,
8920              LeAudioDeviceGroup* group) {
8921             group->SetState(types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
8922 
8923             state_machine_callbacks->StatusReportCb(group_id, GroupStreamStatus::STREAMING);
8924           },
8925           group_id, base::Unretained(this->state_machine_callbacks_), std::move(group)));
8926 
8927   SyncOnMainLoop();
8928 
8929   /* verify AttachToStream was called while stream was not yet created. */
8930   ASSERT_TRUE(attach_to_stream_scheduled);
8931 
8932   // Expect two iso channel to be fed with data
8933   uint8_t cis_count_out = 2;
8934   uint8_t cis_count_in = 0;
8935   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
8936   SyncOnMainLoop();
8937 }
8938 
TEST_F(UnicastTest,LateStreamConnectBasedOnContextTypeNotFullyConnected)8939 TEST_F(UnicastTest, LateStreamConnectBasedOnContextTypeNotFullyConnected) {
8940   uint8_t group_size = 2;
8941   int group_id = 2;
8942 
8943   /* Scenario
8944    * 1. Device A is connected
8945    * 2. Stream creation to Device A has been started
8946    * 3. Stream is stopped
8947    * 4. Device B is connected but has ongoing operations of available context types read.
8948    * 5. Device B sends available context type  read response
8949    * 6. Make sure AttachToStream was NOT called for Device B since it is not in a CONNECTED state
8950    * yet
8951    */
8952 
8953   // Report working CSIS
8954   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
8955 
8956   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
8957           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
8958 
8959   const RawAddress test_address0 = GetTestAddress(0);
8960   const RawAddress test_address1 = GetTestAddress(1);
8961 
8962   // First earbud connects
8963   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
8964                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
8965   // Start streaming
8966   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
8967   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
8968   LeAudioClient::Get()->GroupSetActive(group_id);
8969   SyncOnMainLoop();
8970 
8971   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
8972   auto group = streaming_groups.at(group_id);
8973 
8974   // Stop streaming - simulate suspend timeout passed, alarm executing
8975   StopStreaming(group_id);
8976   fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
8977   SyncOnMainLoop();
8978 
8979   // Second earbud connects and is set to Getting Ready state
8980   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
8981                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
8982                     true /*connect_through_csis*/);
8983   auto device1 = group->GetNextDevice(group->GetFirstDevice());
8984   device1->SetConnectionState(DeviceConnectState::CONNECTED_AUTOCONNECT_GETTING_READY);
8985 
8986   // Resume but block the final streaming state - keep the group in transition
8987   stay_at_qos_config_in_start_stream = true;
8988   UpdateLocalSourceMetadata(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC);
8989   LocalAudioSourceResume(false);
8990 
8991   // Do not expect to attach the device on context update as it is not fully connected
8992   EXPECT_CALL(mock_state_machine_, AttachToStream(_, _, _)).Times(0);
8993   InjectAvailableContextTypes(test_address1, 2, types::kLeAudioContextAllRemoteSinkOnly,
8994                               types::AudioContexts(0), false);
8995 
8996   Mock::VerifyAndClearExpectations(&mock_state_machine_);
8997   SyncOnMainLoop();
8998 }
8999 
TEST_F(UnicastTest,CheckDeviceIsNotAttachedToStreamWhenNotNeeded)9000 TEST_F(UnicastTest, CheckDeviceIsNotAttachedToStreamWhenNotNeeded) {
9001   uint8_t group_size = 2;
9002   int group_id = 2;
9003 
9004   /* Scenario
9005    * 1. Two devices A and B are connect. Both Devices have all available
9006    * contexts types
9007    * 2. Stream creation to Device A and B has been started
9008    * 3. Device B notified us with new available Context Types - while Group is
9009    * not yet streaming
9010    * 4. Make sure AttachToStream was not called for Device B since it is taking
9011    * part in Stream creation already
9012    */
9013 
9014   // Report working CSIS
9015   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
9016 
9017   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
9018           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
9019 
9020   const RawAddress test_address0 = GetTestAddress(0);
9021   const RawAddress test_address1 = GetTestAddress(1);
9022 
9023   // First earbud connects
9024   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
9025                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
9026 
9027   // Second earbud connects
9028   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
9029                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
9030                     true /*connect_through_csis*/);
9031 
9032   // Start streaming
9033   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
9034   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
9035   LeAudioClient::Get()->GroupSetActive(group_id);
9036   SyncOnMainLoop();
9037 
9038   // Block streaming state
9039   stay_at_qos_config_in_start_stream = true;
9040 
9041   UpdateLocalSourceMetadata(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC);
9042   LocalAudioSourceResume(false);
9043 
9044   SyncOnMainLoop();
9045   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
9046 
9047   InjectAvailableContextTypes(test_address1, 2, types::kLeAudioContextAllRemoteSinkOnly,
9048                               types::AudioContexts(0), false);
9049 
9050   // Now simulate group is finally streaming
9051   auto group = streaming_groups.at(group_id);
9052   do_in_main_thread(base::BindOnce(
9053           [](int group_id,
9054              bluetooth::le_audio::LeAudioGroupStateMachine::Callbacks* state_machine_callbacks,
9055              LeAudioDeviceGroup* group) {
9056             group->SetState(types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
9057 
9058             state_machine_callbacks->StatusReportCb(group_id, GroupStreamStatus::STREAMING);
9059           },
9060           group_id, base::Unretained(this->state_machine_callbacks_), std::move(group)));
9061 
9062   SyncOnMainLoop();
9063 
9064   /* verify AttachToStream was NOT called while stream was not yet created. */
9065   ASSERT_FALSE(attach_to_stream_scheduled);
9066 
9067   // Expect two iso channel to be fed with data
9068   uint8_t cis_count_out = 2;
9069   uint8_t cis_count_in = 0;
9070   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
9071   SyncOnMainLoop();
9072 }
9073 
TEST_F(UnicastTest,ReconnectedDeviceAndAttachedToStreamBecauseOfAvailableContextTypeChange)9074 TEST_F(UnicastTest, ReconnectedDeviceAndAttachedToStreamBecauseOfAvailableContextTypeChange) {
9075   com::android::bluetooth::flags::provider_->le_ase_read_multiple_variable(true);
9076 
9077   uint8_t group_size = 2;
9078   int group_id = 2;
9079 
9080   /* Scenario
9081    * 1. Two devices A and B are streaming
9082    * 2. Device A Release ASE and removes all available context types
9083    * 3. Device B keeps streaming
9084    * 4. Device A disconnectes
9085    * 5. Device A reconnect
9086    * 6. Device A has context available for streaming  and should be attached to the stream
9087    */
9088 
9089   // Report working CSIS
9090   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
9091 
9092   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
9093           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
9094 
9095   const RawAddress test_address0 = GetTestAddress(0);
9096   const RawAddress test_address1 = GetTestAddress(1);
9097 
9098   // First earbud connects
9099   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
9100                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
9101 
9102   // Second earbud connects
9103   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
9104                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
9105                     true /*connect_through_csis*/);
9106 
9107   // Start streaming
9108   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
9109   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
9110   LeAudioClient::Get()->GroupSetActive(group_id);
9111   SyncOnMainLoop();
9112 
9113   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
9114 
9115   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
9116   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
9117   SyncOnMainLoop();
9118 
9119   // Expect two iso channel to be fed with data
9120   uint8_t cis_count_out = 2;
9121   uint8_t cis_count_in = 0;
9122   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
9123 
9124   /* Get group and Device A */
9125   ASSERT_NE(0lu, streaming_groups.count(group_id));
9126   auto group = streaming_groups.at(group_id);
9127   ASSERT_NE(group, nullptr);
9128   auto device = group->GetFirstDevice();
9129 
9130   /* Simulate available context type being cleared */
9131   InjectAvailableContextTypes(device->address_, device->conn_id_, types::AudioContexts(0),
9132                               types::AudioContexts(0));
9133 
9134   /* Simulate ASE releasing and CIS Disconnection */
9135   for (auto& ase : device->ases_) {
9136     /* Releasing state */
9137     if (!ase.active) {
9138       continue;
9139     }
9140 
9141     std::vector<uint8_t> releasing_state = {
9142             ase.id, static_cast<uint8_t>(types::AseState::BTA_LE_AUDIO_ASE_STATE_RELEASING)};
9143     InjectNotificationEvent(device->address_, device->conn_id_, ase.hdls.val_hdl, releasing_state);
9144     SyncOnMainLoop();
9145     InjectCisDisconnected(group_id, ase.cis_conn_hdl);
9146     SyncOnMainLoop();
9147   }
9148 
9149   cis_count_out = 1;
9150   cis_count_in = 0;
9151   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
9152 
9153   /* Device A will disconnect, and do not reconnect automatically */
9154   ON_CALL(mock_gatt_interface_, Open(_, device->address_, BTM_BLE_DIRECT_CONNECTION, _))
9155           .WillByDefault(Return());
9156 
9157   /* Disconnect first device */
9158   auto conn_id = device->conn_id_;
9159   InjectDisconnectedEvent(conn_id, GATT_CONN_TERMINATE_PEER_USER);
9160   SyncOnMainLoop();
9161 
9162   /* For background connect, test needs to Inject Connected Event.
9163    * Note that initial available_snk_context_types_ available_src_context_types_ will
9164    * be read after reconnection, which should bring device to the stream again. */
9165 
9166   InjectConnectedEvent(device->address_, conn_id);
9167   SyncOnMainLoop();
9168 
9169   /* Check single device is streaming */
9170   cis_count_out = 2;
9171   cis_count_in = 0;
9172   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
9173 }
9174 
TEST_F(UnicastTest,ReconnectedDeviceNotAttachedToStreamBecauseOfNotAvailableContext)9175 TEST_F(UnicastTest, ReconnectedDeviceNotAttachedToStreamBecauseOfNotAvailableContext) {
9176   uint8_t group_size = 2;
9177   int group_id = 2;
9178 
9179   /* Scenario
9180    * 1. Two devices A and B are streaming
9181    * 2. Device A Release ASE and removes all available context types
9182    * 3. Device B keeps streaming
9183    * 4. Device A disconnectes
9184    * 5. Device A reconnect and should not be attached to the stream
9185    */
9186 
9187   // Report working CSIS
9188   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
9189 
9190   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
9191           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
9192 
9193   const RawAddress test_address0 = GetTestAddress(0);
9194   const RawAddress test_address1 = GetTestAddress(1);
9195 
9196   // First earbud connects
9197   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
9198                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
9199 
9200   // Second earbud connects
9201   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
9202                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
9203                     true /*connect_through_csis*/);
9204 
9205   // Start streaming
9206   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
9207   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
9208   LeAudioClient::Get()->GroupSetActive(group_id);
9209   SyncOnMainLoop();
9210 
9211   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
9212 
9213   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
9214   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
9215   SyncOnMainLoop();
9216 
9217   // Expect two iso channel to be fed with data
9218   uint8_t cis_count_out = 2;
9219   uint8_t cis_count_in = 0;
9220   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
9221 
9222   /* Get group and Device A */
9223   ASSERT_NE(0lu, streaming_groups.count(group_id));
9224   auto group = streaming_groups.at(group_id);
9225   ASSERT_NE(group, nullptr);
9226   auto device = group->GetFirstDevice();
9227 
9228   /* Simulate available context type being cleared */
9229   InjectAvailableContextTypes(device->address_, device->conn_id_, types::AudioContexts(0),
9230                               types::AudioContexts(0));
9231 
9232   /* Simulate ASE releasing and CIS Disconnection */
9233   for (auto& ase : device->ases_) {
9234     /* Releasing state */
9235     if (!ase.active) {
9236       continue;
9237     }
9238 
9239     std::vector<uint8_t> releasing_state = {
9240             ase.id, static_cast<uint8_t>(types::AseState::BTA_LE_AUDIO_ASE_STATE_RELEASING)};
9241     InjectNotificationEvent(device->address_, device->conn_id_, ase.hdls.val_hdl, releasing_state);
9242     SyncOnMainLoop();
9243     InjectCisDisconnected(group_id, ase.cis_conn_hdl);
9244     SyncOnMainLoop();
9245   }
9246 
9247   cis_count_out = 1;
9248   cis_count_in = 0;
9249   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
9250 
9251   /* Device A will disconnect, and do not reconnect automatically */
9252   ON_CALL(mock_gatt_interface_, Open(_, device->address_, BTM_BLE_DIRECT_CONNECTION, _))
9253           .WillByDefault(Return());
9254 
9255   /* Disconnect first device */
9256   auto conn_id = device->conn_id_;
9257   InjectDisconnectedEvent(conn_id, GATT_CONN_TERMINATE_PEER_USER);
9258   SyncOnMainLoop();
9259 
9260   /* For background connect, test needs to Inject Connected Event.
9261    * Since after reconnect Android reads available context types, make sure
9262    * 0 is read */
9263   available_snk_context_types_ = 0;
9264   available_src_context_types_ = 0;
9265 
9266   InjectConnectedEvent(device->address_, conn_id);
9267   SyncOnMainLoop();
9268 
9269   /* Check single device is streaming */
9270   cis_count_out = 1;
9271   cis_count_in = 0;
9272   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
9273 }
9274 
TEST_F(UnicastTest,TwoEarbuds2ndReleaseAseRemoveAvailableContextAndBack)9275 TEST_F(UnicastTest, TwoEarbuds2ndReleaseAseRemoveAvailableContextAndBack) {
9276   uint8_t group_size = 2;
9277   int group_id = 2;
9278 
9279   /* Scenario
9280    * 1. Two devices A and B are streaming
9281    * 2. Device A Release ASE and removes all available context types
9282    * 3. Device B keeps streaming
9283    * 4. Device A sets available context types
9284    * 5. Device A should be attached to the stream
9285    */
9286 
9287   // Report working CSIS
9288   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
9289 
9290   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
9291           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
9292 
9293   const RawAddress test_address0 = GetTestAddress(0);
9294   const RawAddress test_address1 = GetTestAddress(1);
9295 
9296   // First earbud connects
9297   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
9298                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
9299 
9300   // Second earbud connects
9301   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
9302                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
9303                     true /*connect_through_csis*/);
9304 
9305   // Start streaming
9306   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
9307   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
9308   LeAudioClient::Get()->GroupSetActive(group_id);
9309   SyncOnMainLoop();
9310 
9311   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
9312 
9313   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
9314   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
9315   SyncOnMainLoop();
9316 
9317   // Expect two iso channel to be fed with data
9318   uint8_t cis_count_out = 2;
9319   uint8_t cis_count_in = 0;
9320   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
9321 
9322   /* Get group and Device A */
9323   ASSERT_NE(0lu, streaming_groups.count(group_id));
9324   auto group = streaming_groups.at(group_id);
9325   ASSERT_NE(group, nullptr);
9326   auto device = group->GetFirstDevice();
9327 
9328   /* Simulate available context type being cleared */
9329   InjectAvailableContextTypes(device->address_, device->conn_id_, types::AudioContexts(0),
9330                               types::AudioContexts(0));
9331 
9332   /* Simulate ASE releasing and CIS Disconnection */
9333   for (auto& ase : device->ases_) {
9334     /* Releasing state */
9335     if (!ase.active) {
9336       continue;
9337     }
9338 
9339     std::vector<uint8_t> releasing_state = {
9340             ase.id, static_cast<uint8_t>(types::AseState::BTA_LE_AUDIO_ASE_STATE_RELEASING)};
9341     InjectNotificationEvent(device->address_, device->conn_id_, ase.hdls.val_hdl, releasing_state);
9342     SyncOnMainLoop();
9343     InjectCisDisconnected(group_id, ase.cis_conn_hdl);
9344     SyncOnMainLoop();
9345   }
9346 
9347   cis_count_out = 1;
9348   cis_count_in = 0;
9349   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
9350 
9351   /* Bring back available context types */
9352   InjectAvailableContextTypes(device->address_, device->conn_id_, types::kLeAudioContextAllTypes,
9353                               types::kLeAudioContextAllTypes);
9354 
9355   /* Check both devices are streaming */
9356   cis_count_out = 2;
9357   cis_count_in = 0;
9358   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
9359 }
9360 
TEST_F(UnicastTest,StartStream_AvailableContextTypeNotifiedLater)9361 TEST_F(UnicastTest, StartStream_AvailableContextTypeNotifiedLater) {
9362   uint8_t group_size = 2;
9363   int group_id = 2;
9364 
9365   available_snk_context_types_ = 0;
9366 
9367   /* Scenario (Devices A and B called "Remote")
9368    * 1. Remote  does supports all the context types, but has NO available
9369    * contexts at the beginning
9370    * 2. After connection Remote add Available context types
9371    * 3. Android start stream with MEDIA
9372    * 4. Make sure stream will be started
9373    */
9374 
9375   // Report working CSIS
9376   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
9377 
9378   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
9379           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
9380 
9381   const RawAddress test_address0 = GetTestAddress(0);
9382   const RawAddress test_address1 = GetTestAddress(1);
9383 
9384   // First earbud connects
9385   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
9386                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
9387 
9388   // Second earbud connects
9389   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
9390                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
9391                     true /*connect_through_csis*/);
9392 
9393   // Inject Supported and available context types
9394   auto sink_available_contexts = types::kLeAudioContextAllRemoteSinkOnly;
9395   auto source_available_contexts = types::kLeAudioContextAllRemoteSource;
9396 
9397   InjectAvailableContextTypes(test_address0, 1, sink_available_contexts, source_available_contexts);
9398   InjectAvailableContextTypes(test_address1, 2, sink_available_contexts, source_available_contexts);
9399   // Start streaming
9400   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
9401   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
9402   LeAudioClient::Get()->GroupSetActive(group_id);
9403   SyncOnMainLoop();
9404 
9405   BidirectionalPair<AudioContexts> contexts = {
9406           .sink = types::AudioContexts(types::LeAudioContextType::MEDIA),
9407           .source = types::AudioContexts()};
9408 
9409   EXPECT_CALL(mock_state_machine_,
9410               StartStream(_, bluetooth::le_audio::types::LeAudioContextType::MEDIA, contexts, _))
9411           .Times(1);
9412 
9413   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
9414   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
9415   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
9416 
9417   // Expect two iso channel to be fed with data
9418   uint8_t cis_count_out = 2;
9419   uint8_t cis_count_in = 0;
9420   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
9421 }
9422 
TEST_F(UnicastTest,ModifyContextTypeOnDeviceA_WhileDeviceB_IsDisconnected)9423 TEST_F(UnicastTest, ModifyContextTypeOnDeviceA_WhileDeviceB_IsDisconnected) {
9424   uint8_t group_size = 2;
9425   int group_id = 2;
9426 
9427   /* Scenario (Device A and B called Remote)
9428    * 1. Remote set does supports all the context types and make them available
9429    * 2. Android start stream with MEDIA, verify it works.
9430    * 3. Android stops the stream
9431    * 4. Device B disconnects
9432    * 5. Device A removes Media from Available Contexts
9433    * 6. Android start stream with MEDIA, verify it will not be started
9434    */
9435 
9436   // Report working CSIS
9437   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
9438 
9439   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
9440           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
9441 
9442   const RawAddress test_address0 = GetTestAddress(0);
9443   const RawAddress test_address1 = GetTestAddress(1);
9444 
9445   // First earbud connects
9446   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
9447                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
9448 
9449   // Second earbud connects
9450   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
9451                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
9452                     true /*connect_through_csis*/);
9453 
9454   // Start streaming
9455   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
9456   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
9457   LeAudioClient::Get()->GroupSetActive(group_id);
9458   SyncOnMainLoop();
9459 
9460   BidirectionalPair<AudioContexts> contexts = {
9461           .sink = types::AudioContexts(types::LeAudioContextType::MEDIA),
9462           .source = types::AudioContexts()};
9463 
9464   EXPECT_CALL(mock_state_machine_,
9465               StartStream(_, bluetooth::le_audio::types::LeAudioContextType::MEDIA, contexts, _))
9466           .Times(1);
9467 
9468   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
9469 
9470   SyncOnMainLoop();
9471   Mock::VerifyAndClearExpectations(&mock_state_machine_);
9472   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
9473   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
9474 
9475   // Expect two iso channel to be fed with data
9476   uint8_t cis_count_out = 2;
9477   uint8_t cis_count_in = 0;
9478   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
9479 
9480   // Stop
9481   StopStreaming(group_id);
9482   // simulate suspend timeout passed, alarm executing
9483   fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
9484   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
9485 
9486   // Device B got disconnected and will not reconnect.
9487   ON_CALL(mock_gatt_interface_, Open(_, test_address1, BTM_BLE_DIRECT_CONNECTION, _))
9488           .WillByDefault(Return());
9489   InjectDisconnectedEvent(2, GATT_CONN_TERMINATE_PEER_USER);
9490   SyncOnMainLoop();
9491 
9492   // Device A changes available context type
9493   // Inject Supported and available context types
9494   auto sink_supported_context = types::kLeAudioContextAllRemoteSinkOnly;
9495   sink_supported_context.unset(LeAudioContextType::MEDIA);
9496   sink_supported_context.set(LeAudioContextType::UNSPECIFIED);
9497 
9498   auto source_supported_context = types::kLeAudioContextAllRemoteSource;
9499   source_supported_context.set(LeAudioContextType::UNSPECIFIED);
9500 
9501   InjectSupportedContextTypes(test_address0, 1, sink_supported_context, source_supported_context);
9502   InjectAvailableContextTypes(test_address0, 1, sink_supported_context, source_supported_context);
9503 
9504   /* Android starts stream. */
9505   EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, _)).Times(0);
9506 
9507   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id, AUDIO_SOURCE_INVALID, false,
9508                  false);
9509   SyncOnMainLoop();
9510 
9511   Mock::VerifyAndClearExpectations(&mock_state_machine_);
9512 }
9513 
TEST_F(UnicastTest,StartStreamToUnsupportedContextTypeUsingUnspecified)9514 TEST_F(UnicastTest, StartStreamToUnsupportedContextTypeUsingUnspecified) {
9515   uint8_t group_size = 2;
9516   int group_id = 2;
9517 
9518   /* Scenario (Devices A and B called "Remote")
9519    * 1. Remote  does supports all the context types and make them available
9520    * 2. Remote removes SoundEffect from the supported and available context
9521    * types
9522    * 3. Android start stream with SoundEffects
9523    * 4. Make sure stream will be started with Unspecified context type
9524    */
9525 
9526   // Report working CSIS
9527   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
9528 
9529   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
9530           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
9531 
9532   const RawAddress test_address0 = GetTestAddress(0);
9533   const RawAddress test_address1 = GetTestAddress(1);
9534 
9535   // First earbud connects
9536   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
9537                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
9538 
9539   // Second earbud connects
9540   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
9541                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
9542                     true /*connect_through_csis*/);
9543 
9544   // Inject Supported and available context types
9545   auto sink_supported_context = types::kLeAudioContextAllRemoteSinkOnly;
9546   sink_supported_context.unset(LeAudioContextType::SOUNDEFFECTS);
9547   sink_supported_context.set(LeAudioContextType::UNSPECIFIED);
9548 
9549   auto source_supported_context = types::kLeAudioContextAllRemoteSource;
9550   source_supported_context.set(LeAudioContextType::UNSPECIFIED);
9551 
9552   InjectSupportedContextTypes(test_address0, 1, sink_supported_context, source_supported_context);
9553   InjectAvailableContextTypes(test_address0, 1, sink_supported_context, source_supported_context);
9554   InjectSupportedContextTypes(test_address1, 2, sink_supported_context, source_supported_context);
9555   InjectAvailableContextTypes(test_address1, 2, sink_supported_context, source_supported_context);
9556   // Start streaming
9557   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
9558   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
9559   LeAudioClient::Get()->GroupSetActive(group_id);
9560   SyncOnMainLoop();
9561 
9562   BidirectionalPair<AudioContexts> contexts = {
9563           .sink = types::AudioContexts(types::LeAudioContextType::UNSPECIFIED),
9564           .source = types::AudioContexts(0)};
9565 
9566   EXPECT_CALL(
9567           mock_state_machine_,
9568           StartStream(_, bluetooth::le_audio::types::LeAudioContextType::SOUNDEFFECTS, contexts, _))
9569           .Times(1);
9570 
9571   StartStreaming(AUDIO_USAGE_ASSISTANCE_SONIFICATION, AUDIO_CONTENT_TYPE_SONIFICATION, group_id);
9572 
9573   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
9574   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
9575   SyncOnMainLoop();
9576 
9577   // Expect two iso channel to be fed with data
9578   uint8_t cis_count_out = 2;
9579   uint8_t cis_count_in = 0;
9580   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
9581 }
9582 
TEST_F(UnicastTest,StartStreamToUnsupportedContextTypeUnspecifiedNotAvailable)9583 TEST_F(UnicastTest, StartStreamToUnsupportedContextTypeUnspecifiedNotAvailable) {
9584   uint8_t group_size = 2;
9585   int group_id = 2;
9586 
9587   /* Scenario (Device A and B called Remote)
9588    * 1. Remote does supports all the context types and make them available
9589    * 2. Remote removes SoundEffect from the Available Context Types
9590    * 3. Remote also removes UNSPECIFIED from the Available Context Types.
9591    * 4. Android start stream with SoundEffects
9592    * 5. Make sure stream will be NOT be started
9593    */
9594 
9595   // Report working CSIS
9596   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
9597 
9598   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
9599           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
9600 
9601   const RawAddress test_address0 = GetTestAddress(0);
9602   const RawAddress test_address1 = GetTestAddress(1);
9603 
9604   // First earbud connects
9605   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
9606                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
9607 
9608   // Second earbud connects
9609   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
9610                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
9611                     true /*connect_through_csis*/);
9612 
9613   // Inject Supported and available context types
9614   auto sink_supported_context = types::kLeAudioContextAllRemoteSinkOnly;
9615   sink_supported_context.unset(LeAudioContextType::SOUNDEFFECTS);
9616   sink_supported_context.set(LeAudioContextType::UNSPECIFIED);
9617 
9618   auto source_supported_context = types::kLeAudioContextAllRemoteSource;
9619   source_supported_context.set(LeAudioContextType::UNSPECIFIED);
9620 
9621   InjectSupportedContextTypes(test_address0, 1, sink_supported_context, source_supported_context);
9622   InjectSupportedContextTypes(test_address1, 2, sink_supported_context, source_supported_context);
9623 
9624   auto sink_available_context = sink_supported_context;
9625   sink_available_context.unset(LeAudioContextType::UNSPECIFIED);
9626 
9627   auto source_available_context = source_supported_context;
9628   source_available_context.unset(LeAudioContextType::UNSPECIFIED);
9629 
9630   InjectAvailableContextTypes(test_address0, 1, sink_available_context, source_available_context);
9631   InjectAvailableContextTypes(test_address1, 2, sink_available_context, source_available_context);
9632   // Start streaming
9633   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
9634   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
9635   LeAudioClient::Get()->GroupSetActive(group_id);
9636   SyncOnMainLoop();
9637 
9638   BidirectionalPair<AudioContexts> contexts = {
9639           .sink = types::AudioContexts(types::LeAudioContextType::UNSPECIFIED),
9640           .source = types::AudioContexts()};
9641 
9642   EXPECT_CALL(
9643           mock_state_machine_,
9644           StartStream(_, bluetooth::le_audio::types::LeAudioContextType::SOUNDEFFECTS, contexts, _))
9645           .Times(0);
9646 
9647   StartStreaming(AUDIO_USAGE_ASSISTANCE_SONIFICATION, AUDIO_CONTENT_TYPE_SONIFICATION, group_id,
9648                  AUDIO_SOURCE_INVALID, false, false);
9649 
9650   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
9651   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
9652   SyncOnMainLoop();
9653 }
9654 
TEST_F(UnicastTest,StartStreamToSupportedContextTypeThenMixUnavailable)9655 TEST_F(UnicastTest, StartStreamToSupportedContextTypeThenMixUnavailable) {
9656   uint8_t group_size = 2;
9657   int group_id = 2;
9658 
9659   /* Scenario (Device A and B called Remote)
9660    * 1. Remote set does supports all the context types and make them available
9661    * 2. Abdriud start stream with MEDIA, verify it works.
9662    * 3. Stream becomes to be mixed with Soundeffect and Media - verify metadata
9663    *    update
9664    * 4. Android Stop stream.
9665    * 5. Remote removes SoundEffect from the supported and available context
9666    * types
9667    * 6. Android start stream with MEDIA, verify it works.
9668    * 7. Stream becomes to be mixed with Soundeffect and Media
9669    * 8. Make sure metadata updated does not contain unavailable context
9670    *    note: eventually, Audio framework should not give us unwanted context
9671    * types
9672    */
9673 
9674   // Report working CSIS
9675   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
9676 
9677   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
9678           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
9679 
9680   const RawAddress test_address0 = GetTestAddress(0);
9681   const RawAddress test_address1 = GetTestAddress(1);
9682 
9683   // First earbud connects
9684   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
9685                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
9686 
9687   // Second earbud connects
9688   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
9689                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
9690                     true /*connect_through_csis*/);
9691 
9692   // Start streaming
9693   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
9694   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
9695   LeAudioClient::Get()->GroupSetActive(group_id);
9696   SyncOnMainLoop();
9697 
9698   BidirectionalPair<AudioContexts> contexts = {
9699           .sink = types::AudioContexts(types::LeAudioContextType::MEDIA),
9700           .source = types::AudioContexts()};
9701 
9702   EXPECT_CALL(mock_state_machine_,
9703               StartStream(_, bluetooth::le_audio::types::LeAudioContextType::MEDIA, contexts, _))
9704           .Times(1);
9705 
9706   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
9707 
9708   SyncOnMainLoop();
9709   Mock::VerifyAndClearExpectations(&mock_state_machine_);
9710   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
9711   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
9712 
9713   ASSERT_NE(0lu, streaming_groups.count(group_id));
9714   auto group = streaming_groups.at(group_id);
9715 
9716   // Expect two iso channel to be fed with data
9717   uint8_t cis_count_out = 2;
9718   uint8_t cis_count_in = 0;
9719   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
9720 
9721   contexts.sink = types::AudioContexts(types::LeAudioContextType::MEDIA |
9722                                        types::LeAudioContextType::SOUNDEFFECTS);
9723   EXPECT_CALL(mock_state_machine_,
9724               StartStream(_, bluetooth::le_audio::types::LeAudioContextType::MEDIA, contexts, _))
9725           .Times(1);
9726 
9727   /* Simulate metadata update, expect upadate , metadata */
9728   std::vector<struct playback_track_metadata> tracks = {
9729           {{AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, 0},
9730            {AUDIO_USAGE_ASSISTANCE_SONIFICATION, AUDIO_CONTENT_TYPE_SONIFICATION, 0}}};
9731   UpdateLocalSourceMetadata(tracks);
9732   SyncOnMainLoop();
9733 
9734   Mock::VerifyAndClearExpectations(&mock_state_machine_);
9735 
9736   /* Stop stream */
9737   StopStreaming(group_id);
9738   // simulate suspend timeout passed, alarm executing
9739   fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
9740   SyncOnMainLoop();
9741 
9742   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
9743 
9744   // Inject Supported and available context types
9745   auto sink_supported_context = types::kLeAudioContextAllRemoteSinkOnly;
9746   sink_supported_context.unset(LeAudioContextType::SOUNDEFFECTS);
9747   sink_supported_context.set(LeAudioContextType::UNSPECIFIED);
9748 
9749   auto source_supported_context = types::kLeAudioContextAllRemoteSource;
9750   source_supported_context.set(LeAudioContextType::UNSPECIFIED);
9751 
9752   InjectSupportedContextTypes(test_address0, 1, sink_supported_context, source_supported_context);
9753   InjectAvailableContextTypes(test_address0, 1, sink_supported_context, source_supported_context);
9754   InjectSupportedContextTypes(test_address1, 2, sink_supported_context, source_supported_context);
9755   InjectAvailableContextTypes(test_address1, 2, sink_supported_context, source_supported_context);
9756 
9757   // Verify cache has been removed due to available context change
9758   ASSERT_EQ(nullptr, group->GetCachedConfiguration(types::LeAudioContextType::MEDIA));
9759   /* Start Media again */
9760   contexts.sink = types::AudioContexts(types::LeAudioContextType::MEDIA);
9761   EXPECT_CALL(mock_state_machine_,
9762               StartStream(_, bluetooth::le_audio::types::LeAudioContextType::MEDIA, contexts, _))
9763           .Times(1);
9764 
9765   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
9766 
9767   SyncOnMainLoop();
9768 
9769   // Verify cache has been rebuilt
9770   ASSERT_NE(nullptr, group->GetCachedConfiguration(types::LeAudioContextType::MEDIA));
9771   ASSERT_TRUE(group->GetCachedConfiguration(types::LeAudioContextType::MEDIA)
9772                       ->confs.get(le_audio::types::kLeAudioDirectionSink)
9773                       .size());
9774 
9775   Mock::VerifyAndClearExpectations(&mock_state_machine_);
9776   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
9777   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
9778 
9779   // Expect two iso channel to be fed with data
9780   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
9781 
9782   /* Update metadata, and do not expect new context type*/
9783   EXPECT_CALL(mock_state_machine_,
9784               StartStream(_, bluetooth::le_audio::types::LeAudioContextType::MEDIA, contexts, _))
9785           .Times(1);
9786 
9787   /* Simulate metadata update */
9788   UpdateLocalSourceMetadata(tracks);
9789   SyncOnMainLoop();
9790   Mock::VerifyAndClearExpectations(&mock_state_machine_);
9791 }
9792 
TEST_F(UnicastTest,TwoEarbuds2ndDisconnected)9793 TEST_F(UnicastTest, TwoEarbuds2ndDisconnected) {
9794   uint8_t group_size = 2;
9795   int group_id = 2;
9796 
9797   // Report working CSIS
9798   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
9799 
9800   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
9801           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
9802 
9803   // First earbud
9804   const RawAddress test_address0 = GetTestAddress(0);
9805   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
9806                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
9807 
9808   // Second earbud
9809   const RawAddress test_address1 = GetTestAddress(1);
9810   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
9811                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
9812                     true /*connect_through_csis*/);
9813 
9814   // Audio sessions are started only when device gets active
9815   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
9816   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
9817   LeAudioClient::Get()->GroupSetActive(group_id);
9818   SyncOnMainLoop();
9819 
9820   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
9821   ASSERT_NE(0lu, streaming_groups.count(group_id));
9822   auto group = streaming_groups.at(group_id);
9823 
9824   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
9825   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
9826   SyncOnMainLoop();
9827   ASSERT_EQ(2, group->NumOfConnected());
9828 
9829   // Expect two iso channels to be fed with data
9830   uint8_t cis_count_out = 2;
9831   uint8_t cis_count_in = 0;
9832   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
9833 
9834   // Disconnect one device and expect the group to keep on streaming
9835   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(0);
9836   auto device = group->GetFirstDevice();
9837   for (auto& ase : device->ases_) {
9838     InjectCisDisconnected(group_id, ase.cis_conn_hdl);
9839   }
9840 
9841   /* Disconnect ACL and do not reconnect. */
9842   ON_CALL(mock_gatt_interface_, Open(_, device->address_, BTM_BLE_DIRECT_CONNECTION, _))
9843           .WillByDefault(Return());
9844   EXPECT_CALL(mock_gatt_interface_, Open(_, device->address_, BTM_BLE_DIRECT_CONNECTION, false))
9845           .Times(1);
9846 
9847   // Record NumOfConnected when groupStateMachine_ gets notified about the
9848   // disconnection
9849   int num_of_connected = 0;
9850   ON_CALL(mock_state_machine_, ProcessHciNotifAclDisconnected(_, _))
9851           .WillByDefault(
9852                   [&num_of_connected](LeAudioDeviceGroup* group, LeAudioDevice* /*leAudioDevice*/) {
9853                     num_of_connected = group->NumOfConnected();
9854                   });
9855 
9856   auto conn_id = device->conn_id_;
9857   InjectDisconnectedEvent(device->conn_id_, GATT_CONN_TERMINATE_PEER_USER);
9858   SyncOnMainLoop();
9859 
9860   // Make sure the state machine knows about the disconnected device
9861   ASSERT_EQ(1, num_of_connected);
9862 
9863   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
9864   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
9865 
9866   // Expect one channel ISO Data to be sent
9867   cis_count_out = 1;
9868   cis_count_in = 0;
9869   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
9870 
9871   InjectConnectedEvent(device->address_, conn_id);
9872   SyncOnMainLoop();
9873 
9874   // Expect two iso channels to be fed with data
9875   cis_count_out = 2;
9876   cis_count_in = 0;
9877   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
9878 }
9879 
TEST_F(UnicastTest,TwoEarbudsStreamingProfileDisconnect)9880 TEST_F(UnicastTest, TwoEarbudsStreamingProfileDisconnect) {
9881   uint8_t group_size = 2;
9882   int group_id = 2;
9883 
9884   // Report working CSIS
9885   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
9886 
9887   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
9888           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
9889 
9890   // First earbud
9891   const RawAddress test_address0 = GetTestAddress(0);
9892   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
9893                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
9894 
9895   // Second earbud
9896   const RawAddress test_address1 = GetTestAddress(1);
9897   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
9898                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
9899                     true /*connect_through_csis*/);
9900 
9901   // Audio sessions are started only when device gets active
9902   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
9903   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
9904   LeAudioClient::Get()->GroupSetActive(group_id);
9905   SyncOnMainLoop();
9906 
9907   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
9908 
9909   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
9910   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
9911   SyncOnMainLoop();
9912 
9913   // Expect two iso channels to be fed with data
9914   uint8_t cis_count_out = 2;
9915   uint8_t cis_count_in = 0;
9916   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
9917 
9918   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(1);
9919 
9920   /* Do not inject OPEN_EVENT by default */
9921   ON_CALL(mock_gatt_interface_, Open(_, _, _, _)).WillByDefault(DoAll(Return()));
9922   ON_CALL(mock_gatt_interface_, Close(_)).WillByDefault(DoAll(Return()));
9923   ON_CALL(mock_btm_interface_, AclDisconnectFromHandle(_, _)).WillByDefault(DoAll(Return()));
9924 
9925   DisconnectLeAudioNoDisconnectedEvtExpected(test_address0, 1);
9926   DisconnectLeAudioNoDisconnectedEvtExpected(test_address1, 2);
9927 
9928   EXPECT_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _))
9929           .Times(2);
9930 
9931   InjectDisconnectedEvent(1);
9932   InjectDisconnectedEvent(2);
9933 
9934   SyncOnMainLoop();
9935   Mock::VerifyAndClearExpectations(&mock_state_machine_);
9936   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
9937 }
9938 
TEST_F(UnicastTest,TwoEarbudsStreamingProfileDisconnectStreamStopTimeout)9939 TEST_F(UnicastTest, TwoEarbudsStreamingProfileDisconnectStreamStopTimeout) {
9940   uint8_t group_size = 2;
9941   int group_id = 2;
9942 
9943   // Report working CSIS
9944   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
9945 
9946   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
9947           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
9948 
9949   // First earbud
9950   const RawAddress test_address0 = GetTestAddress(0);
9951   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
9952                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
9953 
9954   // Second earbud
9955   const RawAddress test_address1 = GetTestAddress(1);
9956   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
9957                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
9958                     true /*connect_through_csis*/);
9959 
9960   // Audio sessions are started only when device gets active
9961   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
9962   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
9963   LeAudioClient::Get()->GroupSetActive(group_id);
9964   SyncOnMainLoop();
9965 
9966   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
9967 
9968   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
9969   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
9970   SyncOnMainLoop();
9971 
9972   // Expect two iso channels to be fed with data
9973   uint8_t cis_count_out = 2;
9974   uint8_t cis_count_in = 0;
9975   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
9976 
9977   // Expect StopStream to be called before Close or ACL Disconnect is called.
9978   ON_CALL(mock_state_machine_, StopStream(_)).WillByDefault([](LeAudioDeviceGroup* group) {
9979     /* Stub the process of stopping stream, just set the target state.
9980      * this simulates issue with stopping the stream
9981      */
9982     group->SetTargetState(types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE);
9983   });
9984 
9985   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(2);
9986   EXPECT_CALL(mock_gatt_interface_, Close(_)).Times(0);
9987   EXPECT_CALL(mock_btm_interface_, AclDisconnectFromHandle(_, _)).Times(0);
9988 
9989   do_in_main_thread(base::Bind(&LeAudioClient::Disconnect, base::Unretained(LeAudioClient::Get()),
9990                                test_address0));
9991   do_in_main_thread(base::Bind(&LeAudioClient::Disconnect, base::Unretained(LeAudioClient::Get()),
9992                                test_address1));
9993 
9994   SyncOnMainLoop();
9995   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
9996   Mock::VerifyAndClearExpectations(&mock_btm_interface_);
9997   Mock::VerifyAndClearExpectations(&mock_state_machine_);
9998 
9999   /* Now stream is trying to be stopped and devices are about to be
10000    * disconnected. Simulate stop stream failure and timeout fired. Make sure
10001    * code will not try to do recovery connect
10002    */
10003   ON_CALL(mock_btm_interface_, AclDisconnectFromHandle(_, _)).WillByDefault(DoAll(Return()));
10004   EXPECT_CALL(mock_gatt_interface_, Close(_)).Times(0);
10005   EXPECT_CALL(mock_btm_interface_, AclDisconnectFromHandle(_, _)).Times(2);
10006 
10007   ASSERT_NE(0lu, streaming_groups.count(group_id));
10008   auto group = streaming_groups.at(group_id);
10009   ASSERT_TRUE(group != nullptr);
10010   ASSERT_GT(group->NumOfConnected(), 0);
10011 
10012   state_machine_callbacks_->OnStateTransitionTimeout(group_id);
10013   SyncOnMainLoop();
10014 
10015   Mock::VerifyAndClearExpectations(&mock_btm_interface_);
10016   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
10017 
10018   auto device = group->GetFirstDevice();
10019   ASSERT_TRUE(device != nullptr);
10020   ASSERT_NE(device->GetConnectionState(), DeviceConnectState::DISCONNECTING_AND_RECOVER);
10021   device = group->GetNextDevice(device);
10022   ASSERT_TRUE(device != nullptr);
10023   ASSERT_NE(device->GetConnectionState(), DeviceConnectState::DISCONNECTING_AND_RECOVER);
10024 }
10025 
TEST_F(UnicastTest,EarbudsWithStereoSinkMonoSourceSupporting32kHz)10026 TEST_F(UnicastTest, EarbudsWithStereoSinkMonoSourceSupporting32kHz) {
10027   const RawAddress test_address0 = GetTestAddress(0);
10028   int group_id = 0;
10029   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
10030                                 codec_spec_conf::kLeAudioLocationFrontLeft, default_channel_cnt,
10031                                 default_channel_cnt, 0x0024,
10032                                 /* source sample freq 32/16khz */ true, /*add_csis*/
10033                                 true,                                   /*add_cas*/
10034                                 true,                                   /*add_pacs*/
10035                                 default_ase_cnt /*add_ascs_cnt*/);
10036   EXPECT_CALL(mock_audio_hal_client_callbacks_,
10037               OnConnectionState(ConnectionState::CONNECTED, test_address0))
10038           .Times(1);
10039   ConnectLeAudio(test_address0);
10040 
10041   // LeAudioCodecConfiguration received_af_sink_config;
10042   const LeAudioCodecConfiguration expected_af_sink_config = {
10043           .num_channels = 2,
10044           .sample_rate = bluetooth::audio::le_audio::kSampleRate32000,
10045           .bits_per_sample = bluetooth::audio::le_audio::kBitsPerSample16,
10046           .data_interval_us = LeAudioCodecConfiguration::kInterval10000Us,
10047   };
10048 
10049   // Audio sessions are started only when device gets active
10050   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
10051   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(expected_af_sink_config, _, _)).Times(1);
10052   LeAudioClient::Get()->GroupSetActive(group_id);
10053   SyncOnMainLoop();
10054 }
10055 
TEST_F(UnicastTest,TwoEarbudsWithSourceSupporting32kHz)10056 TEST_F(UnicastTest, TwoEarbudsWithSourceSupporting32kHz) {
10057   const RawAddress test_address0 = GetTestAddress(0);
10058   int group_id = 0;
10059   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
10060                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
10061                                 default_channel_cnt, 0x0024,
10062                                 /* source sample freq 32/16khz */ true, /*add_csis*/
10063                                 true,                                   /*add_cas*/
10064                                 true,                                   /*add_pacs*/
10065                                 default_ase_cnt /*add_ascs_cnt*/);
10066   EXPECT_CALL(mock_audio_hal_client_callbacks_,
10067               OnConnectionState(ConnectionState::CONNECTED, test_address0))
10068           .Times(1);
10069   ConnectLeAudio(test_address0);
10070 
10071   // LeAudioCodecConfiguration received_af_sink_config;
10072   const LeAudioCodecConfiguration expected_af_sink_config = {
10073           .num_channels = 2,
10074           .sample_rate = bluetooth::audio::le_audio::kSampleRate32000,
10075           .bits_per_sample = bluetooth::audio::le_audio::kBitsPerSample16,
10076           .data_interval_us = LeAudioCodecConfiguration::kInterval10000Us,
10077   };
10078 
10079   // Audio sessions are started only when device gets active
10080   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
10081   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(expected_af_sink_config, _, _)).Times(1);
10082   LeAudioClient::Get()->GroupSetActive(group_id);
10083   SyncOnMainLoop();
10084 }
10085 
TEST_F(UnicastTest,MicrophoneAttachToCurrentMediaScenario)10086 TEST_F(UnicastTest, MicrophoneAttachToCurrentMediaScenario) {
10087   const RawAddress test_address0 = GetTestAddress(0);
10088   int group_id = bluetooth::groups::kGroupUnknown;
10089 
10090   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
10091                                 codec_spec_conf::kLeAudioLocationFrontLeft, default_channel_cnt,
10092                                 default_channel_cnt, 0x0024, false /*add_csis*/, true /*add_cas*/,
10093                                 true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
10094                                 0 /*rank*/);
10095   EXPECT_CALL(mock_audio_hal_client_callbacks_,
10096               OnConnectionState(ConnectionState::CONNECTED, test_address0))
10097           .Times(1);
10098   EXPECT_CALL(mock_audio_hal_client_callbacks_,
10099               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
10100           .WillOnce(DoAll(SaveArg<1>(&group_id)));
10101 
10102   ConnectLeAudio(test_address0);
10103   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
10104 
10105   // Audio sessions are started only when device gets active
10106   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
10107   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
10108   LeAudioClient::Get()->GroupSetActive(group_id);
10109   SyncOnMainLoop();
10110 
10111   // When the local audio source resumes we have no knowledge of recording
10112   EXPECT_CALL(mock_state_machine_,
10113               StartStream(_, bluetooth::le_audio::types::LeAudioContextType::MEDIA, _, _))
10114           .Times(1);
10115 
10116   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id, AUDIO_SOURCE_INVALID);
10117   SyncOnMainLoop();
10118 
10119   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
10120   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
10121 
10122   // Verify Data transfer on one audio source cis
10123   uint8_t cis_count_out = 1;
10124   uint8_t cis_count_in = 0;
10125   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
10126 
10127   // When the local audio sink resumes we should reconfigure
10128   EXPECT_CALL(mock_state_machine_,
10129               ConfigureStream(_, bluetooth::le_audio::types::LeAudioContextType::LIVE, _, _, _))
10130           .Times(1);
10131   EXPECT_CALL(*mock_le_audio_source_hal_client_, ReconfigurationComplete()).Times(1);
10132 
10133   // Update metadata on local audio sink
10134   UpdateLocalSinkMetadata(AUDIO_SOURCE_MIC);
10135 
10136   // Resume on local audio sink
10137   ASSERT_NE(unicast_sink_hal_cb_, nullptr);
10138   do_in_main_thread(
10139           base::BindOnce([](LeAudioSinkAudioHalClient::Callbacks* cb) { cb->OnAudioResume(); },
10140                          unicast_sink_hal_cb_));
10141 
10142   /* The above will trigger reconfiguration. After that Audio Hal action
10143    * is needed to restart the stream */
10144   SyncOnMainLoop();
10145 
10146   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
10147   Mock::VerifyAndClearExpectations(&mock_state_machine_);
10148 
10149   LocalAudioSourceResume();
10150   do_in_main_thread(
10151           base::BindOnce([](LeAudioSinkAudioHalClient::Callbacks* cb) { cb->OnAudioResume(); },
10152                          unicast_sink_hal_cb_));
10153   SyncOnMainLoop();
10154 
10155   auto group = streaming_groups.at(group_id);
10156   group->PrintDebugState();
10157 
10158   // Verify Data transfer on one audio source and sink cis
10159   cis_count_out = 1;
10160   cis_count_in = 1;
10161   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 60);
10162 
10163   // Stop
10164   StopStreaming(group_id);
10165   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
10166 
10167   // Release
10168   EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop()).Times(1);
10169   EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(1);
10170   EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(1);
10171   do_in_main_thread(base::BindOnce(
10172           [](LeAudioClient* client) { client->GroupSetActive(bluetooth::groups::kGroupUnknown); },
10173           LeAudioClient::Get()));
10174   SyncOnMainLoop();
10175 
10176   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
10177 }
10178 
TEST_F(UnicastTest,SwitchBetweenMicrophoneAndSoundEffectScenario)10179 TEST_F(UnicastTest, SwitchBetweenMicrophoneAndSoundEffectScenario) {
10180   const RawAddress test_address0 = GetTestAddress(0);
10181   int group_id = bluetooth::groups::kGroupUnknown;
10182 
10183   /* Scenario:
10184    * 1. User starts Recording - this creates bidiretional CISes
10185    * 2. User stops recording  - this starts suspend timeout (500ms)
10186    * 3. Since user touch the screen it generates touch tone - this shall reuse existing CISes when
10187    * it happens 500ms before stop
10188    */
10189   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
10190                                 codec_spec_conf::kLeAudioLocationFrontLeft, default_channel_cnt,
10191                                 default_channel_cnt, 0x0024, false /*add_csis*/, true /*add_cas*/,
10192                                 true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
10193                                 0 /*rank*/);
10194   EXPECT_CALL(mock_audio_hal_client_callbacks_,
10195               OnConnectionState(ConnectionState::CONNECTED, test_address0))
10196           .Times(1);
10197   EXPECT_CALL(mock_audio_hal_client_callbacks_,
10198               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
10199           .WillOnce(DoAll(SaveArg<1>(&group_id)));
10200 
10201   ConnectLeAudio(test_address0);
10202   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
10203 
10204   // Audio sessions are started only when device gets active
10205   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
10206   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
10207   LeAudioClient::Get()->GroupSetActive(group_id);
10208   SyncOnMainLoop();
10209 
10210   // When the local audio source resumes we have no knowledge of recording
10211   EXPECT_CALL(mock_state_machine_,
10212               StartStream(_, bluetooth::le_audio::types::LeAudioContextType::LIVE, _, _))
10213           .Times(1);
10214 
10215   log::info("Start Microphone recording - bidirectional CISes are expected");
10216   UpdateLocalSinkMetadata(AUDIO_SOURCE_MIC);
10217   LocalAudioSinkResume();
10218 
10219   ASSERT_EQ(0, get_func_call_count("alarm_set_on_mloop"));
10220   SyncOnMainLoop();
10221 
10222   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
10223   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
10224   Mock::VerifyAndClearExpectations(&mock_state_machine_);
10225 
10226   // Verify Data transfer on one audio source cis
10227   uint8_t cis_count_out = 0;
10228   uint8_t cis_count_in = 1;
10229   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 60);
10230 
10231   log::info("Suspend microphone recording - suspend timeout is not fired");
10232   LocalAudioSinkSuspend();
10233   SyncOnMainLoop();
10234 
10235   log::info("Expect VBC and Suspend timeouts to be started");
10236   ASSERT_EQ(2, get_func_call_count("alarm_set_on_mloop"));
10237   ASSERT_EQ(0, get_func_call_count("alarm_cancel"));
10238 
10239   log::info("Resume local source with touch tone - expect suspend timeout to be canceled");
10240 
10241   UpdateLocalSourceMetadata(AUDIO_USAGE_ASSISTANCE_SONIFICATION, AUDIO_CONTENT_TYPE_SONIFICATION);
10242   LocalAudioSourceResume();
10243   SyncOnMainLoop();
10244 
10245   log::info("Expect VBC and Suspend timeouts to be started");
10246   ASSERT_EQ(2, get_func_call_count("alarm_set_on_mloop"));
10247 
10248   auto group = streaming_groups.at(group_id);
10249   group->PrintDebugState();
10250 
10251   // Verify Data transfer on one audio source and sink cis
10252   cis_count_out = 1;
10253   cis_count_in = 0;
10254   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 60);
10255 }
10256 
10257 /* When a certain context is unavailable and not supported we should stream
10258  * as UNSPECIFIED for the backwards compatibility.
10259  * Since UNSPECIFIED is available, put the UNSPECIFIED into the metadata instead
10260  * What we can do now is to keep streaming (and reconfigure if needed for the
10261  * use case).
10262  */
TEST_F(UnicastTest,UpdateNotSupportedContextTypeUnspecifiedAvailable)10263 TEST_F(UnicastTest, UpdateNotSupportedContextTypeUnspecifiedAvailable) {
10264   // TODO(b/352686917). Remove the test when flag will be removing
10265   com::android::bluetooth::flags::provider_->leaudio_speed_up_reconfiguration_between_call(false);
10266 
10267   const RawAddress test_address0 = GetTestAddress(0);
10268   int group_id = bluetooth::groups::kGroupUnknown;
10269 
10270   available_snk_context_types_ =
10271           (types::LeAudioContextType::RINGTONE | types::LeAudioContextType::CONVERSATIONAL |
10272            types::LeAudioContextType::UNSPECIFIED | types::LeAudioContextType::MEDIA)
10273                   .value();
10274   supported_snk_context_types_ = available_snk_context_types_;
10275   available_src_context_types_ = available_snk_context_types_;
10276   supported_src_context_types_ = available_src_context_types_;
10277 
10278   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
10279                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
10280                                 default_channel_cnt, 0x0004, false /*add_csis*/, true /*add_cas*/,
10281                                 true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
10282                                 0 /*rank*/);
10283   EXPECT_CALL(mock_audio_hal_client_callbacks_,
10284               OnConnectionState(ConnectionState::CONNECTED, test_address0))
10285           .Times(1);
10286   EXPECT_CALL(mock_audio_hal_client_callbacks_,
10287               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
10288           .WillOnce(DoAll(SaveArg<1>(&group_id)));
10289 
10290   ConnectLeAudio(test_address0);
10291   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
10292 
10293   // Start streaming
10294   uint8_t cis_count_out = 1;
10295   uint8_t cis_count_in = 0;
10296 
10297   LeAudioClient::Get()->SetInCall(true);
10298 
10299   // Audio sessions are started only when device gets active
10300   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
10301   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
10302   LeAudioClient::Get()->GroupSetActive(group_id);
10303   SyncOnMainLoop();
10304 
10305   StartStreaming(AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE, AUDIO_CONTENT_TYPE_UNKNOWN, group_id);
10306   LocalAudioSourceResume();
10307   LocalAudioSinkResume();
10308 
10309   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
10310   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
10311   SyncOnMainLoop();
10312 
10313   // Verify Data transfer on one audio source cis
10314   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
10315 
10316   LeAudioClient::Get()->SetInCall(false);
10317   LocalAudioSinkSuspend();
10318 
10319   /* We should use GAME configuration, but do not send the GAME context type, as
10320    * it is not available on the remote device.
10321    */
10322   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(0);
10323   types::BidirectionalPair<types::AudioContexts> contexts = {
10324           .sink = types::AudioContexts(types::LeAudioContextType::UNSPECIFIED),
10325           .source = types::AudioContexts()};
10326   EXPECT_CALL(mock_state_machine_, StartStream(_, types::LeAudioContextType::GAME, contexts, _))
10327           .Times(1);
10328   UpdateLocalSourceMetadata(AUDIO_USAGE_GAME, AUDIO_CONTENT_TYPE_UNKNOWN, false);
10329   SyncOnMainLoop();
10330 }
10331 
TEST_F(UnicastTest,UpdateNotSupportedContextTypeUnspecifiedAvailable_SpeedUpReconfigFlagEnabled)10332 TEST_F(UnicastTest, UpdateNotSupportedContextTypeUnspecifiedAvailable_SpeedUpReconfigFlagEnabled) {
10333   com::android::bluetooth::flags::provider_->leaudio_speed_up_reconfiguration_between_call(true);
10334 
10335   const RawAddress test_address0 = GetTestAddress(0);
10336   int group_id = bluetooth::groups::kGroupUnknown;
10337 
10338   available_snk_context_types_ =
10339           (types::LeAudioContextType::RINGTONE | types::LeAudioContextType::CONVERSATIONAL |
10340            types::LeAudioContextType::UNSPECIFIED | types::LeAudioContextType::MEDIA)
10341                   .value();
10342   supported_snk_context_types_ = available_snk_context_types_;
10343   available_src_context_types_ = available_snk_context_types_;
10344   supported_src_context_types_ = available_src_context_types_;
10345 
10346   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
10347                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
10348                                 default_channel_cnt, 0x0004, false /*add_csis*/, true /*add_cas*/,
10349                                 true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
10350                                 0 /*rank*/);
10351   EXPECT_CALL(mock_audio_hal_client_callbacks_,
10352               OnConnectionState(ConnectionState::CONNECTED, test_address0))
10353           .Times(1);
10354   EXPECT_CALL(mock_audio_hal_client_callbacks_,
10355               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
10356           .WillOnce(DoAll(SaveArg<1>(&group_id)));
10357 
10358   ConnectLeAudio(test_address0);
10359   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
10360 
10361   // Start streaming
10362   uint8_t cis_count_out = 1;
10363   uint8_t cis_count_in = 0;
10364 
10365   LeAudioClient::Get()->SetInCall(true);
10366 
10367   // Audio sessions are started only when device gets active
10368   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
10369   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
10370   LeAudioClient::Get()->GroupSetActive(group_id);
10371   SyncOnMainLoop();
10372 
10373   StartStreaming(AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE, AUDIO_CONTENT_TYPE_UNKNOWN, group_id);
10374   LocalAudioSourceResume();
10375   LocalAudioSinkResume();
10376 
10377   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
10378   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
10379   SyncOnMainLoop();
10380 
10381   // Verify Data transfer on one audio source cis
10382   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
10383 
10384   LeAudioClient::Get()->SetInCall(false);
10385   LocalAudioSinkSuspend();
10386 
10387   /* We should use GAME configuration, but do not send the GAME context type, as
10388    * it is not available on the remote device.
10389    */
10390   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(0);
10391   types::BidirectionalPair<types::AudioContexts> contexts = {
10392           .sink = types::AudioContexts(types::LeAudioContextType::UNSPECIFIED),
10393           .source = types::AudioContexts()};
10394   EXPECT_CALL(mock_state_machine_, StartStream(_, types::LeAudioContextType::GAME, contexts, _))
10395           .Times(1);
10396   UpdateLocalSourceMetadata(AUDIO_USAGE_GAME, AUDIO_CONTENT_TYPE_UNKNOWN, false);
10397   SyncOnMainLoop();
10398 }
10399 
10400 /* Some bidirectional scenarios are triggered by the local sink, local source
10401  * metadata or the In Call preference callback call. Since each call invalidates
10402  * previous context source, make sure that getting all of these in a sequence,
10403  * always results with one bidirectional context, so that the remote device
10404  * is not confused about our intentions.
10405  */
TEST_F(UnicastTest,UpdateMultipleBidirContextTypes)10406 TEST_F(UnicastTest, UpdateMultipleBidirContextTypes) {
10407   // TODO(b/352686917). Remove the test when flag will be removing
10408   com::android::bluetooth::flags::provider_->leaudio_speed_up_reconfiguration_between_call(false);
10409 
10410   const RawAddress test_address0 = GetTestAddress(0);
10411   int group_id = bluetooth::groups::kGroupUnknown;
10412 
10413   available_snk_context_types_ = (types::LeAudioContextType::CONVERSATIONAL |
10414                                   types::LeAudioContextType::GAME | types::LeAudioContextType::LIVE)
10415                                          .value();
10416   supported_snk_context_types_ =
10417           available_snk_context_types_ |
10418           types::AudioContexts(types::LeAudioContextType::UNSPECIFIED).value();
10419   available_src_context_types_ = available_snk_context_types_;
10420   supported_src_context_types_ =
10421           available_src_context_types_ |
10422           types::AudioContexts(types::LeAudioContextType::UNSPECIFIED).value();
10423 
10424   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationAnyLeft,
10425                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
10426                                 default_channel_cnt, 0x0024, false /*add_csis*/, true /*add_cas*/,
10427                                 true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
10428                                 0 /*rank*/);
10429   EXPECT_CALL(mock_audio_hal_client_callbacks_,
10430               OnConnectionState(ConnectionState::CONNECTED, test_address0))
10431           .Times(1);
10432   EXPECT_CALL(mock_audio_hal_client_callbacks_,
10433               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
10434           .WillOnce(DoAll(SaveArg<1>(&group_id)));
10435 
10436   ConnectLeAudio(test_address0);
10437   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
10438 
10439   // Audio sessions are started only when device gets active
10440   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
10441   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
10442   LeAudioClient::Get()->GroupSetActive(group_id);
10443   SyncOnMainLoop();
10444 
10445   // When the local audio sink resumes expect only LIVE context
10446   types::BidirectionalPair<types::AudioContexts> contexts = {
10447           .sink = types::AudioContexts(types::LeAudioContextType::LIVE),
10448           .source = types::AudioContexts(types::LeAudioContextType::LIVE)};
10449   EXPECT_CALL(mock_state_machine_,
10450               StartStream(_, bluetooth::le_audio::types::LeAudioContextType::LIVE, contexts, _))
10451           .Times(1);
10452 
10453   // 1) Start the recording. Sink resume will trigger the reconfiguration
10454   // ---------------------------------------------------------------------
10455   ASSERT_NE(nullptr, unicast_sink_hal_cb_);
10456   UpdateLocalSinkMetadata(AUDIO_SOURCE_MIC);
10457   LocalAudioSinkResume();
10458 
10459   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
10460   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
10461   Mock::VerifyAndClearExpectations(&mock_state_machine_);
10462 
10463   /* After the reconfiguration the local Audio Sink HAL has to resume again */
10464   LocalAudioSourceResume();
10465   LocalAudioSinkResume();
10466 
10467   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
10468   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
10469   Mock::VerifyAndClearExpectations(&mock_state_machine_);
10470 
10471   // Verify Data transfer on one audio source and sink cis
10472   uint8_t cis_count_out = 1;
10473   uint8_t cis_count_in = 1;
10474   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 40);
10475 
10476   // Stop
10477   StopStreaming(group_id);
10478   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
10479 
10480   // 2) Now set in call preference to get CONVERSATIONAL into the mix
10481   // -----------------------------------------------------------------
10482   LeAudioClient::Get()->SetInCall(true);
10483 
10484   // Verify that we only got CONVERSATIONAL context and no LIVE
10485   contexts = {.sink = types::AudioContexts(types::LeAudioContextType::CONVERSATIONAL),
10486               .source = types::AudioContexts(types::LeAudioContextType::CONVERSATIONAL)};
10487   EXPECT_CALL(mock_state_machine_,
10488               StartStream(_, bluetooth::le_audio::types::LeAudioContextType::CONVERSATIONAL,
10489                           contexts, _))
10490           .Times(1);
10491 
10492   // Start with ringtone on local source
10493   ASSERT_NE(nullptr, unicast_sink_hal_cb_);
10494   StartStreaming(AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE, AUDIO_CONTENT_TYPE_UNKNOWN, group_id);
10495 
10496   // Resume both directions
10497   LocalAudioSourceResume();
10498   LocalAudioSinkResume();
10499 
10500   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
10501   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
10502   Mock::VerifyAndClearExpectations(&mock_state_machine_);
10503 
10504   // Verify Data transfer on one audio source cis
10505   cis_count_out = 1;
10506   cis_count_in = 1;
10507   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 40);
10508 
10509   // 3) Disable call so we could go to GAME
10510   // ---------------------------------------
10511   LeAudioClient::Get()->SetInCall(false);
10512 
10513   /* Start the game on local source - expect no previous sink (LIVE) metadata */
10514   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(0);
10515   contexts = {.sink = types::AudioContexts(types::LeAudioContextType::GAME),
10516               .source = types::AudioContexts(types::LeAudioContextType::GAME)};
10517   EXPECT_CALL(mock_state_machine_, StartStream(_, types::LeAudioContextType::GAME, contexts, _))
10518           .Times(1);
10519   UpdateLocalSourceMetadata(AUDIO_USAGE_GAME, AUDIO_CONTENT_TYPE_UNKNOWN, false);
10520 
10521   /* If the above triggers reconfiguration, Audio Hal action is needed to
10522    * restart the stream.
10523    */
10524   LocalAudioSourceResume();
10525   LocalAudioSinkResume();
10526   Mock::VerifyAndClearExpectations(&mock_state_machine_);
10527 
10528   // 4) Stop streaming
10529   // ------------------
10530   StopStreaming(group_id);
10531   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
10532 
10533   // Release
10534   EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop()).Times(1);
10535   EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(1);
10536   EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(1);
10537   do_in_main_thread(base::BindOnce(
10538           [](LeAudioClient* client) { client->GroupSetActive(bluetooth::groups::kGroupUnknown); },
10539           LeAudioClient::Get()));
10540   SyncOnMainLoop();
10541 }
10542 
TEST_F(UnicastTest,UpdateMultipleBidirContextTypes_SpeedUpReconfigFlagEnabled)10543 TEST_F(UnicastTest, UpdateMultipleBidirContextTypes_SpeedUpReconfigFlagEnabled) {
10544   com::android::bluetooth::flags::provider_->leaudio_speed_up_reconfiguration_between_call(true);
10545 
10546   const RawAddress test_address0 = GetTestAddress(0);
10547   int group_id = bluetooth::groups::kGroupUnknown;
10548 
10549   available_snk_context_types_ = (types::LeAudioContextType::CONVERSATIONAL |
10550                                   types::LeAudioContextType::GAME | types::LeAudioContextType::LIVE)
10551                                          .value();
10552   supported_snk_context_types_ =
10553           available_snk_context_types_ |
10554           types::AudioContexts(types::LeAudioContextType::UNSPECIFIED).value();
10555   available_src_context_types_ = available_snk_context_types_;
10556   supported_src_context_types_ =
10557           available_src_context_types_ |
10558           types::AudioContexts(types::LeAudioContextType::UNSPECIFIED).value();
10559 
10560   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationAnyLeft,
10561                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
10562                                 default_channel_cnt, 0x0024, false /*add_csis*/, true /*add_cas*/,
10563                                 true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
10564                                 0 /*rank*/);
10565   EXPECT_CALL(mock_audio_hal_client_callbacks_,
10566               OnConnectionState(ConnectionState::CONNECTED, test_address0))
10567           .Times(1);
10568   EXPECT_CALL(mock_audio_hal_client_callbacks_,
10569               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
10570           .WillOnce(DoAll(SaveArg<1>(&group_id)));
10571 
10572   ConnectLeAudio(test_address0);
10573   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
10574 
10575   // Audio sessions are started only when device gets active
10576   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
10577   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
10578   LeAudioClient::Get()->GroupSetActive(group_id);
10579   SyncOnMainLoop();
10580 
10581   // When the local audio sink resumes expect only LIVE context
10582   types::BidirectionalPair<types::AudioContexts> contexts = {
10583           .sink = types::AudioContexts(types::LeAudioContextType::LIVE),
10584           .source = types::AudioContexts(types::LeAudioContextType::LIVE)};
10585   EXPECT_CALL(mock_state_machine_,
10586               StartStream(_, bluetooth::le_audio::types::LeAudioContextType::LIVE, contexts, _))
10587           .Times(1);
10588 
10589   log::info("Step 1 Start the recording. Sink resume will trigger the reconfiguration");
10590   // ---------------------------------------------------------------------
10591   ASSERT_NE(nullptr, unicast_sink_hal_cb_);
10592   UpdateLocalSinkMetadata(AUDIO_SOURCE_MIC);
10593   LocalAudioSinkResume();
10594 
10595   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
10596   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
10597   Mock::VerifyAndClearExpectations(&mock_state_machine_);
10598 
10599   log::info("After the reconfiguration the local Audio Sink HAL has to resume again");
10600 
10601   LocalAudioSourceResume();
10602   LocalAudioSinkResume();
10603 
10604   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
10605   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
10606   Mock::VerifyAndClearExpectations(&mock_state_machine_);
10607 
10608   log::info("Verify Data transfer on one audio source and sink cis");
10609 
10610   uint8_t cis_count_out = 1;
10611   uint8_t cis_count_in = 1;
10612   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 40);
10613 
10614   log::info("Step 2 Now set in call preference to get CONVERSATIONAL into the mix");
10615   // -----------------------------------------------------------------
10616 
10617   EXPECT_CALL(*mock_le_audio_source_hal_client_, SuspendedForReconfiguration()).Times(0);
10618   EXPECT_CALL(*mock_le_audio_source_hal_client_, CancelStreamingRequest()).Times(0);
10619   EXPECT_CALL(*mock_le_audio_source_hal_client_, ReconfigurationComplete()).Times(0);
10620   EXPECT_CALL(mock_state_machine_, ConfigureStream(_, _, _, _, _)).Times(0);
10621   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(0);
10622   LeAudioClient::Get()->SetInCall(true);
10623   SyncOnMainLoop();
10624 
10625   // Verify that we only got CONVERSATIONAL context and no LIVE
10626   contexts = {.sink = types::AudioContexts(types::LeAudioContextType::CONVERSATIONAL),
10627               .source = types::AudioContexts(types::LeAudioContextType::CONVERSATIONAL)};
10628   EXPECT_CALL(mock_state_machine_,
10629               StartStream(_, bluetooth::le_audio::types::LeAudioContextType::CONVERSATIONAL,
10630                           contexts, _))
10631           .Times(1);
10632 
10633   log::info("Start with ringtone on local source");
10634   ASSERT_NE(nullptr, unicast_sink_hal_cb_);
10635   StartStreaming(AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE, AUDIO_CONTENT_TYPE_UNKNOWN, group_id);
10636 
10637   // Resume both directions
10638   LocalAudioSourceResume();
10639   LocalAudioSinkResume();
10640 
10641   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
10642   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
10643   Mock::VerifyAndClearExpectations(&mock_state_machine_);
10644 
10645   // Verify Data transfer on one audio source cis
10646   cis_count_out = 1;
10647   cis_count_in = 1;
10648   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 40);
10649 
10650   log::info("Step 3 Disable call so we could go to GAME");
10651   // ---------------------------------------
10652   EXPECT_CALL(*mock_le_audio_source_hal_client_, SuspendedForReconfiguration()).Times(0);
10653   EXPECT_CALL(*mock_le_audio_source_hal_client_, CancelStreamingRequest()).Times(0);
10654   EXPECT_CALL(*mock_le_audio_source_hal_client_, ReconfigurationComplete()).Times(0);
10655   EXPECT_CALL(mock_state_machine_, ConfigureStream(_, _, _, _, _)).Times(0);
10656   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(0);
10657 
10658   LeAudioClient::Get()->SetInCall(false);
10659   SyncOnMainLoop();
10660   Mock::VerifyAndClearExpectations(&mock_state_machine_);
10661   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
10662 
10663   log::info("Start the game on local source - expect no previous sink (LIVE) metadata");
10664 
10665   /* Stream shall keep streaming */
10666   contexts = {.sink = types::AudioContexts(types::LeAudioContextType::GAME),
10667               .source = types::AudioContexts(types::LeAudioContextType::GAME)};
10668   EXPECT_CALL(mock_state_machine_, StartStream(_, _, contexts, _)).Times(1);
10669 
10670   UpdateLocalSourceMetadata(AUDIO_USAGE_GAME, AUDIO_CONTENT_TYPE_UNKNOWN, false);
10671   LocalAudioSourceResume();
10672   SyncOnMainLoop();
10673 
10674   // Verify Data transfer on one audio source cis
10675   cis_count_out = 1;
10676   cis_count_in = 1;
10677   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 40);
10678   Mock::VerifyAndClearExpectations(&mock_state_machine_);
10679 
10680   log::info(" Step 4 Stop streaming");
10681   // ------------------
10682   StopStreaming(group_id);
10683   SyncOnMainLoop();
10684   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
10685 
10686   // Release
10687   EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop()).Times(1);
10688   EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(1);
10689   EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(1);
10690   do_in_main_thread(base::BindOnce(
10691           [](LeAudioClient* client) { client->GroupSetActive(bluetooth::groups::kGroupUnknown); },
10692           LeAudioClient::Get()));
10693   SyncOnMainLoop();
10694 }
10695 
TEST_F(UnicastTest,UpdateDisableLocalAudioSinkOnGame)10696 TEST_F(UnicastTest, UpdateDisableLocalAudioSinkOnGame) {
10697   const RawAddress test_address0 = GetTestAddress(0);
10698   int group_id = bluetooth::groups::kGroupUnknown;
10699 
10700   available_snk_context_types_ = (types::LeAudioContextType::CONVERSATIONAL |
10701                                   types::LeAudioContextType::GAME | types::LeAudioContextType::LIVE)
10702                                          .value();
10703   supported_snk_context_types_ =
10704           available_snk_context_types_ |
10705           types::AudioContexts(types::LeAudioContextType::UNSPECIFIED).value();
10706   available_src_context_types_ = available_snk_context_types_;
10707   supported_src_context_types_ =
10708           available_src_context_types_ |
10709           types::AudioContexts(types::LeAudioContextType::UNSPECIFIED).value();
10710 
10711   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationAnyLeft,
10712                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
10713                                 default_channel_cnt, 0x0024, false /*add_csis*/, true /*add_cas*/,
10714                                 true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
10715                                 0 /*rank*/);
10716   EXPECT_CALL(mock_audio_hal_client_callbacks_,
10717               OnConnectionState(ConnectionState::CONNECTED, test_address0))
10718           .Times(1);
10719   EXPECT_CALL(mock_audio_hal_client_callbacks_,
10720               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
10721           .WillOnce(DoAll(SaveArg<1>(&group_id)));
10722 
10723   ConnectLeAudio(test_address0);
10724   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
10725 
10726   // Audio sessions are started only when device gets active
10727   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
10728   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
10729   LeAudioClient::Get()->GroupSetActive(group_id);
10730   SyncOnMainLoop();
10731 
10732   // Start GAME stream
10733   types::BidirectionalPair<types::AudioContexts> contexts = {
10734           .sink = types::AudioContexts(types::LeAudioContextType::GAME),
10735           .source = types::AudioContexts(types::LeAudioContextType::GAME)};
10736   EXPECT_CALL(mock_state_machine_,
10737               StartStream(_, bluetooth::le_audio::types::LeAudioContextType::GAME, contexts, _))
10738           .Times(1);
10739 
10740   // 1) Start the recording. Sink resume will trigger the reconfiguration
10741   // ---------------------------------------------------------------------
10742   StartStreaming(AUDIO_USAGE_GAME, AUDIO_CONTENT_TYPE_MUSIC, group_id, AUDIO_SOURCE_MIC);
10743 
10744   SyncOnMainLoop();
10745 
10746   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
10747   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
10748   Mock::VerifyAndClearExpectations(&mock_state_machine_);
10749 
10750   // Verify Data transfer on one audio source and sink cis
10751   uint8_t cis_count_out = 1;
10752   uint8_t cis_count_in = 1;
10753   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 40);
10754 
10755   SyncOnMainLoop();
10756 
10757   // 2) Now Lets suspend MIC and do not expect reconfiguration
10758   // -----------------------------------------------------------------
10759 
10760   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(0);
10761   LocalAudioSinkSuspend();
10762   // simulate suspend timeout passed, alarm executing
10763   fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
10764   SyncOnMainLoop();
10765   Mock::VerifyAndClearExpectations(&mock_state_machine_);
10766 }
10767 
10768 /* Start music when in a call, end the call, continue with music only */
TEST_F(UnicastTest,MusicDuringCallContextTypes)10769 TEST_F(UnicastTest, MusicDuringCallContextTypes) {
10770   // TODO(b/352686917). Remove the test when flag will be removing
10771   com::android::bluetooth::flags::provider_->leaudio_speed_up_reconfiguration_between_call(false);
10772 
10773   const RawAddress test_address0 = GetTestAddress(0);
10774   int group_id = bluetooth::groups::kGroupUnknown;
10775 
10776   available_snk_context_types_ =
10777           (types::LeAudioContextType::CONVERSATIONAL | types::LeAudioContextType::RINGTONE |
10778            types::LeAudioContextType::GAME | types::LeAudioContextType::MEDIA |
10779            types::LeAudioContextType::LIVE | types::LeAudioContextType::NOTIFICATIONS)
10780                   .value();
10781   supported_snk_context_types_ =
10782           available_snk_context_types_ |
10783           types::AudioContexts(types::LeAudioContextType::UNSPECIFIED).value();
10784   available_src_context_types_ = available_snk_context_types_;
10785   available_src_context_types_ &=
10786           ~((types::LeAudioContextType::NOTIFICATIONS | types::LeAudioContextType::MEDIA).value());
10787   supported_src_context_types_ =
10788           available_src_context_types_ |
10789           types::AudioContexts(types::LeAudioContextType::UNSPECIFIED).value();
10790 
10791   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationAnyLeft,
10792                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
10793                                 default_channel_cnt, 0x0024, false /*add_csis*/, true /*add_cas*/,
10794                                 true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
10795                                 0 /*rank*/);
10796   EXPECT_CALL(mock_audio_hal_client_callbacks_,
10797               OnConnectionState(ConnectionState::CONNECTED, test_address0))
10798           .Times(1);
10799   EXPECT_CALL(mock_audio_hal_client_callbacks_,
10800               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
10801           .WillOnce(DoAll(SaveArg<1>(&group_id)));
10802 
10803   ConnectLeAudio(test_address0);
10804   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
10805 
10806   // Audio sessions are started only when device gets active
10807   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
10808   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
10809   LeAudioClient::Get()->GroupSetActive(group_id);
10810   SyncOnMainLoop();
10811 
10812   log::info("TESTPOINT 1: Start with the call first");
10813   // -----------------------------
10814   // CONVERSATIONAL is from In Call preference, and RINGTONE is from metadata
10815   LeAudioClient::Get()->SetInCall(true);
10816   types::BidirectionalPair<types::AudioContexts> contexts = {
10817           .sink = types::AudioContexts(types::LeAudioContextType::RINGTONE |
10818                                        types::LeAudioContextType::CONVERSATIONAL),
10819           .source = types::AudioContexts(types::LeAudioContextType::CONVERSATIONAL)};
10820   EXPECT_CALL(mock_state_machine_,
10821               StartStream(_, bluetooth::le_audio::types::LeAudioContextType::CONVERSATIONAL,
10822                           contexts, _))
10823           .Times(1);
10824   StartStreaming(AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE, AUDIO_CONTENT_TYPE_UNKNOWN, group_id);
10825   LocalAudioSinkResume();
10826 
10827   // Verify
10828   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
10829   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
10830   Mock::VerifyAndClearExpectations(&mock_state_machine_);
10831 
10832   // Verify Data transfer
10833   uint8_t cis_count_out = 1;
10834   uint8_t cis_count_in = 1;
10835   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 40);
10836 
10837   log::info("TESTPOINT 2: Start MEDIA during the call, expect MEDIA only on the remote sink");
10838   contexts = {.sink = types::AudioContexts(types::LeAudioContextType::CONVERSATIONAL |
10839                                            types::LeAudioContextType::MEDIA),
10840               .source = types::AudioContexts(types::LeAudioContextType::CONVERSATIONAL)};
10841   EXPECT_CALL(mock_state_machine_,
10842               StartStream(_, bluetooth::le_audio::types::LeAudioContextType::CONVERSATIONAL,
10843                           contexts, _))
10844           .Times(1);
10845   UpdateLocalSourceMetadata(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, false);
10846   SyncOnMainLoop();
10847 
10848   Mock::VerifyAndClearExpectations(&mock_state_machine_);
10849   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
10850   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
10851 
10852   log::info(
10853           "TESTPOINT 3: Disable In Call preference but do not suspend the local sink. Play "
10854           "notification on the same stream.");
10855   // Verify both context are sent as the metadata.
10856   // ---------------------------------------
10857   LeAudioClient::Get()->SetInCall(false);
10858 
10859   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(0);
10860   contexts = {.sink = types::AudioContexts(types::LeAudioContextType::NOTIFICATIONS |
10861                                            types::LeAudioContextType::CONVERSATIONAL),
10862               .source = types::AudioContexts(types::LeAudioContextType::CONVERSATIONAL)};
10863   EXPECT_CALL(mock_state_machine_,
10864               StartStream(_, types::LeAudioContextType::CONVERSATIONAL, contexts, _))
10865           .Times(1);
10866   UpdateLocalSourceMetadata(AUDIO_USAGE_NOTIFICATION, AUDIO_CONTENT_TYPE_UNKNOWN,
10867                             /*reconfigure=*/false);
10868   Mock::VerifyAndClearExpectations(&mock_state_machine_);
10869   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
10870   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
10871 
10872   log::info("TESTPOINT 4: Disable call so we could go back to MEDIA");
10873   // ---------------------------------------
10874   // Suspend should stop the stream
10875   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(1);
10876   LocalAudioSourceSuspend();
10877   LocalAudioSinkSuspend();
10878   // simulate suspend timeout passed, alarm executing
10879   fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
10880   Mock::VerifyAndClearExpectations(&mock_state_machine_);
10881 
10882   // Restart the stream with MEDIA
10883   contexts = {.sink = types::AudioContexts(types::LeAudioContextType::MEDIA),
10884               .source = types::AudioContexts()};
10885   EXPECT_CALL(mock_state_machine_, StartStream(_, types::LeAudioContextType::MEDIA, contexts, _))
10886           .Times(1);
10887   UpdateLocalSourceMetadata(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC,
10888                             /*reconfigure=*/false);
10889   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
10890   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
10891 
10892   /* The source needs to resume to reconfigure to MEDIA */
10893   LocalAudioSourceResume(/*expect_confirm=*/false);
10894   LocalAudioSourceResume(/*expect_confirm=*/true);
10895   Mock::VerifyAndClearExpectations(&mock_state_machine_);
10896   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
10897   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
10898 
10899   log::info("TESTPOINT 5: Stop streaming");
10900   // ------------------
10901   StopStreaming(group_id);
10902   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
10903 
10904   // Release
10905   EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop()).Times(1);
10906   EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(1);
10907   EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(1);
10908   do_in_main_thread(base::BindOnce(
10909           [](LeAudioClient* client) { client->GroupSetActive(bluetooth::groups::kGroupUnknown); },
10910           LeAudioClient::Get()));
10911   SyncOnMainLoop();
10912 }
10913 
TEST_F(UnicastTest,MetadataUpdateDuringReconfiguration)10914 TEST_F(UnicastTest, MetadataUpdateDuringReconfiguration) {
10915   com::android::bluetooth::flags::provider_->leaudio_speed_up_reconfiguration_between_call(true);
10916   const RawAddress test_address0 = GetTestAddress(0);
10917   int group_id = bluetooth::groups::kGroupUnknown;
10918 
10919   /* Scenario
10920    * 1. Start reconfiguration
10921    * 2. Send metadata update
10922    * 3. Make sure metadata updates are ignored
10923    */
10924   available_snk_context_types_ =
10925           (types::LeAudioContextType::CONVERSATIONAL | types::LeAudioContextType::RINGTONE |
10926            types::LeAudioContextType::GAME | types::LeAudioContextType::MEDIA |
10927            types::LeAudioContextType::LIVE | types::LeAudioContextType::NOTIFICATIONS)
10928                   .value();
10929   supported_snk_context_types_ =
10930           available_snk_context_types_ |
10931           types::AudioContexts(types::LeAudioContextType::UNSPECIFIED).value();
10932   available_src_context_types_ = available_snk_context_types_;
10933   supported_src_context_types_ =
10934           available_src_context_types_ |
10935           types::AudioContexts(types::LeAudioContextType::UNSPECIFIED).value();
10936 
10937   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationAnyLeft,
10938                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
10939                                 default_channel_cnt, 0x0024, false /*add_csis*/, true /*add_cas*/,
10940                                 true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
10941                                 0 /*rank*/);
10942   EXPECT_CALL(mock_audio_hal_client_callbacks_,
10943               OnConnectionState(ConnectionState::CONNECTED, test_address0))
10944           .Times(1);
10945   EXPECT_CALL(mock_audio_hal_client_callbacks_,
10946               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
10947           .WillOnce(DoAll(SaveArg<1>(&group_id)));
10948 
10949   ConnectLeAudio(test_address0);
10950   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
10951 
10952   // Audio sessions are started only when device gets active
10953   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
10954   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
10955   LeAudioClient::Get()->GroupSetActive(group_id);
10956   SyncOnMainLoop();
10957   EXPECT_CALL(mock_state_machine_,
10958               StartStream(_, bluetooth::le_audio::types::LeAudioContextType::MEDIA, _, _))
10959           .Times(1);
10960   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
10961   SyncOnMainLoop();
10962   Mock::VerifyAndClearExpectations(&mock_state_machine_);
10963 
10964   auto group = streaming_groups.at(group_id);
10965 
10966   stay_at_qos_config_in_start_stream = true;
10967   log::info("Reconfigure to conversational and stay in Codec Config");
10968 
10969   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(1);
10970   EXPECT_CALL(mock_state_machine_, ConfigureStream(_, _, _, _, _)).Times(1);
10971 
10972   LeAudioClient::Get()->SetInCall(true);
10973   SyncOnMainLoop();
10974 
10975   ASSERT_TRUE(group->GetState() == types::AseState::BTA_LE_AUDIO_ASE_STATE_CODEC_CONFIGURED);
10976 
10977   log::info("Expect not action on metadata change");
10978 
10979   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(0);
10980   EXPECT_CALL(mock_state_machine_, ConfigureStream(_, _, _, _, _)).Times(0);
10981 
10982   UpdateLocalSourceMetadata(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC);
10983   SyncOnMainLoop();
10984   Mock::VerifyAndClearExpectations(&mock_state_machine_);
10985 }
10986 
TEST_F(UnicastTest,MusicDuringCallContextTypes_SpeedUpReconfigFlagEnabled)10987 TEST_F(UnicastTest, MusicDuringCallContextTypes_SpeedUpReconfigFlagEnabled) {
10988   com::android::bluetooth::flags::provider_->leaudio_speed_up_reconfiguration_between_call(true);
10989 
10990   const RawAddress test_address0 = GetTestAddress(0);
10991   int group_id = bluetooth::groups::kGroupUnknown;
10992 
10993   available_snk_context_types_ =
10994           (types::LeAudioContextType::CONVERSATIONAL | types::LeAudioContextType::RINGTONE |
10995            types::LeAudioContextType::GAME | types::LeAudioContextType::MEDIA |
10996            types::LeAudioContextType::LIVE | types::LeAudioContextType::NOTIFICATIONS)
10997                   .value();
10998   supported_snk_context_types_ =
10999           available_snk_context_types_ |
11000           types::AudioContexts(types::LeAudioContextType::UNSPECIFIED).value();
11001   available_src_context_types_ = available_snk_context_types_;
11002   supported_src_context_types_ =
11003           available_src_context_types_ |
11004           types::AudioContexts(types::LeAudioContextType::UNSPECIFIED).value();
11005 
11006   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationAnyLeft,
11007                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
11008                                 default_channel_cnt, 0x0024, false /*add_csis*/, true /*add_cas*/,
11009                                 true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
11010                                 0 /*rank*/);
11011   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11012               OnConnectionState(ConnectionState::CONNECTED, test_address0))
11013           .Times(1);
11014   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11015               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
11016           .WillOnce(DoAll(SaveArg<1>(&group_id)));
11017 
11018   ConnectLeAudio(test_address0);
11019   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
11020 
11021   // Audio sessions are started only when device gets active
11022   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
11023   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
11024   LeAudioClient::Get()->GroupSetActive(group_id);
11025   SyncOnMainLoop();
11026 
11027   log::info("Step 1 Start with the call first");
11028   // -----------------------------
11029   // CONVERSATIONAL is from In Call preference, and RINGTONE is from metadata
11030   LeAudioClient::Get()->SetInCall(true);
11031   types::BidirectionalPair<types::AudioContexts> contexts = {
11032           .sink = types::AudioContexts(types::LeAudioContextType::RINGTONE |
11033                                        types::LeAudioContextType::CONVERSATIONAL),
11034           .source = types::AudioContexts(types::LeAudioContextType::CONVERSATIONAL)};
11035   EXPECT_CALL(mock_state_machine_,
11036               StartStream(_, bluetooth::le_audio::types::LeAudioContextType::CONVERSATIONAL,
11037                           contexts, _))
11038           .Times(1);
11039   StartStreaming(AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE, AUDIO_CONTENT_TYPE_UNKNOWN, group_id);
11040   LocalAudioSourceResume();
11041   LocalAudioSinkResume();
11042 
11043   // Verify
11044   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
11045   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
11046   Mock::VerifyAndClearExpectations(&mock_state_machine_);
11047 
11048   // Verify Data transfer
11049   uint8_t cis_count_out = 1;
11050   uint8_t cis_count_in = 1;
11051   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 40);
11052 
11053   log::info("Step  2) Start MEDIA during the call, expect MEDIA only on the remote sink");
11054 
11055   contexts = {.sink = types::AudioContexts(types::LeAudioContextType::CONVERSATIONAL |
11056                                            types::LeAudioContextType::MEDIA),
11057               .source = types::AudioContexts(types::LeAudioContextType::CONVERSATIONAL)};
11058   EXPECT_CALL(mock_state_machine_,
11059               StartStream(_, bluetooth::le_audio::types::LeAudioContextType::CONVERSATIONAL,
11060                           contexts, _))
11061           .Times(1);
11062   UpdateLocalSourceMetadata(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, false);
11063   SyncOnMainLoop();
11064 
11065   Mock::VerifyAndClearExpectations(&mock_state_machine_);
11066   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
11067   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
11068 
11069   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(0);
11070   contexts = {.sink = types::AudioContexts(types::LeAudioContextType::MEDIA |
11071                                            types::LeAudioContextType::CONVERSATIONAL),
11072               .source = types::AudioContexts(types::LeAudioContextType::CONVERSATIONAL)};
11073   EXPECT_CALL(mock_state_machine_,
11074               StartStream(_, types::LeAudioContextType::CONVERSATIONAL, contexts, _))
11075           .Times(1);
11076   UpdateLocalSourceMetadata(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC,
11077                             /*reconfigure=*/false);
11078   Mock::VerifyAndClearExpectations(&mock_state_machine_);
11079   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
11080   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
11081 
11082   log::info("Step 3) Disable call so we could go back to MEDIA");
11083   // ---------------------------------------
11084   // Suspend should stop the stream
11085   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(1);
11086   LocalAudioSourceSuspend();
11087   LocalAudioSinkSuspend();
11088   // simulate suspend timeout passed, alarm executing
11089   fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
11090 
11091   LeAudioClient::Get()->SetInCall(false);
11092   SyncOnMainLoop();
11093   Mock::VerifyAndClearExpectations(&mock_state_machine_);
11094 
11095   // Restart the stream with MEDIA
11096   contexts = {.sink = types::AudioContexts(types::LeAudioContextType::MEDIA),
11097               .source = types::AudioContexts()};
11098   EXPECT_CALL(mock_state_machine_, StartStream(_, types::LeAudioContextType::MEDIA, contexts, _))
11099           .Times(1);
11100   UpdateLocalSourceMetadata(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC,
11101                             /*reconfigure=*/false);
11102   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
11103   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
11104 
11105   /* The source needs to resume to reconfigure to MEDIA */
11106   LocalAudioSourceResume(/*expect_confirm=*/false);
11107   LocalAudioSourceResume(/*expect_confirm=*/true);
11108   Mock::VerifyAndClearExpectations(&mock_state_machine_);
11109   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
11110   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
11111 
11112   log::info("Step 3) Stop streaming");
11113 
11114   // ------------------
11115   StopStreaming(group_id);
11116   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
11117 
11118   // Release
11119   EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop()).Times(1);
11120   EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(1);
11121   EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(1);
11122   do_in_main_thread(base::BindOnce(
11123           [](LeAudioClient* client) { client->GroupSetActive(bluetooth::groups::kGroupUnknown); },
11124           LeAudioClient::Get()));
11125   SyncOnMainLoop();
11126 }
11127 
11128 /* When a certain context is unavailable but supported we should not stream that
11129  * context - either stop the stream or eliminate this strim from the mix
11130  * This could be na IOP issue so continue streaming (and reconfigure if needed
11131  * for that use case).
11132  * Since the unavailable context is supported, do not put this context into
11133  * the metadata, and do not replace it with UNSPECIFIED.
11134  */
TEST_F(UnicastTest,StartNotAvailableSupportedContextType)11135 TEST_F(UnicastTest, StartNotAvailableSupportedContextType) {
11136   const RawAddress test_address0 = GetTestAddress(0);
11137   int group_id = bluetooth::groups::kGroupUnknown;
11138 
11139   // EMERGENCYALARM is not available, but supported
11140   available_snk_context_types_ =
11141           (types::LeAudioContextType::RINGTONE | types::LeAudioContextType::CONVERSATIONAL |
11142            types::LeAudioContextType::UNSPECIFIED | types::LeAudioContextType::MEDIA)
11143                   .value();
11144   available_src_context_types_ = available_snk_context_types_;
11145   supported_snk_context_types_ = types::kLeAudioContextAllTypes.value();
11146   supported_src_context_types_ =
11147           (types::kLeAudioContextAllRemoteSource | types::LeAudioContextType::UNSPECIFIED).value();
11148 
11149   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
11150                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
11151                                 default_channel_cnt, 0x0004, false /*add_csis*/, true /*add_cas*/,
11152                                 true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
11153                                 0 /*rank*/);
11154   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11155               OnConnectionState(ConnectionState::CONNECTED, test_address0))
11156           .Times(1);
11157   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11158               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
11159           .WillOnce(DoAll(SaveArg<1>(&group_id)));
11160 
11161   ConnectLeAudio(test_address0);
11162   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
11163 
11164   // Expect configuring to (or staying with) the right configuration but the
11165   // metadata should not get the EMERGENCYALARM context, nor the UNSPECIFIED
11166   // Since the initial config is UNSPECIFIED, then even for sonification events
11167   // we should reconfigure to less generic EMERGENCYALARM scenario
11168   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
11169   types::BidirectionalPair<types::AudioContexts> metadata = {.sink = types::AudioContexts(),
11170                                                              .source = types::AudioContexts()};
11171   EXPECT_CALL(mock_state_machine_,
11172               StartStream(_, types::LeAudioContextType::EMERGENCYALARM, metadata, _))
11173           .Times(0);
11174 
11175   LeAudioClient::Get()->GroupSetActive(group_id);
11176   SyncOnMainLoop();
11177 
11178   StartStreaming(AUDIO_USAGE_EMERGENCY, AUDIO_CONTENT_TYPE_UNKNOWN, group_id, AUDIO_SOURCE_INVALID,
11179                  false, false);
11180 
11181   SyncOnMainLoop();
11182   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
11183   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
11184 }
11185 
11186 /* When a certain context is unavailable and not supported and the UNSPECIFIED
11187  * is not available we should stop the stream.
11188  * For now, stream will not be started in such a case.
11189  * In future we should be able to eliminate this context from the track mix.
11190  */
TEST_F(UnicastTest,StartNotAvailableUnsupportedContextTypeUnspecifiedUnavail)11191 TEST_F(UnicastTest, StartNotAvailableUnsupportedContextTypeUnspecifiedUnavail) {
11192   const RawAddress test_address0 = GetTestAddress(0);
11193   int group_id = bluetooth::groups::kGroupUnknown;
11194 
11195   // EMERGENCYALARM is not available, nor supported
11196   available_snk_context_types_ =
11197           (types::LeAudioContextType::RINGTONE | types::LeAudioContextType::CONVERSATIONAL |
11198            types::LeAudioContextType::MEDIA)
11199                   .value();
11200   available_src_context_types_ = available_snk_context_types_;
11201   supported_snk_context_types_ =
11202           (available_snk_context_types_ | types::LeAudioContextType::UNSPECIFIED).value();
11203   supported_src_context_types_ =
11204           (available_src_context_types_ | types::LeAudioContextType::UNSPECIFIED).value();
11205 
11206   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
11207                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
11208                                 default_channel_cnt, 0x0004, false /*add_csis*/, true /*add_cas*/,
11209                                 true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
11210                                 0 /*rank*/);
11211   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11212               OnConnectionState(ConnectionState::CONNECTED, test_address0))
11213           .Times(1);
11214   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11215               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
11216           .WillOnce(DoAll(SaveArg<1>(&group_id)));
11217 
11218   ConnectLeAudio(test_address0);
11219   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
11220 
11221   // Expect configuring to the default config since the EMERGENCYALARM is
11222   // not on the list of supported contexts and UNSPECIFIED should not be
11223   // in the metadata as it is unavailable.
11224   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
11225   types::BidirectionalPair<types::AudioContexts> metadata = {.sink = types::AudioContexts(),
11226                                                              .source = types::AudioContexts()};
11227   EXPECT_CALL(mock_state_machine_,
11228               StartStream(_, types::LeAudioContextType::EMERGENCYALARM, metadata, _))
11229           .Times(0);
11230 
11231   LeAudioClient::Get()->GroupSetActive(group_id);
11232   SyncOnMainLoop();
11233 
11234   StartStreaming(AUDIO_USAGE_EMERGENCY, AUDIO_CONTENT_TYPE_UNKNOWN, group_id, AUDIO_SOURCE_INVALID,
11235                  false, false);
11236 
11237   SyncOnMainLoop();
11238   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
11239   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
11240 }
11241 
11242 /* This test verifies if we use UNSPCIFIED context when another context is
11243  * unavailable and not supported but UNSPCIFIED is in available audio contexts.
11244  */
TEST_F(UnicastTest,StartNotAvailableUnsupportedContextTypeUnspecifiedAvail)11245 TEST_F(UnicastTest, StartNotAvailableUnsupportedContextTypeUnspecifiedAvail) {
11246   const RawAddress test_address0 = GetTestAddress(0);
11247   int group_id = bluetooth::groups::kGroupUnknown;
11248 
11249   // EMERGENCYALARM is not available, nor supported
11250   available_snk_context_types_ =
11251           (types::LeAudioContextType::RINGTONE | types::LeAudioContextType::CONVERSATIONAL |
11252            types::LeAudioContextType::UNSPECIFIED | types::LeAudioContextType::MEDIA)
11253                   .value();
11254   available_src_context_types_ = available_snk_context_types_;
11255   supported_snk_context_types_ = available_snk_context_types_;
11256   supported_src_context_types_ = available_src_context_types_;
11257 
11258   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
11259                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
11260                                 default_channel_cnt, 0x0004, false /*add_csis*/, true /*add_cas*/,
11261                                 true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
11262                                 0 /*rank*/);
11263   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11264               OnConnectionState(ConnectionState::CONNECTED, test_address0))
11265           .Times(1);
11266   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11267               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
11268           .WillOnce(DoAll(SaveArg<1>(&group_id)));
11269 
11270   ConnectLeAudio(test_address0);
11271   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
11272 
11273   // Expect configuring to the default config since the EMERGENCYALARM is
11274   // not on the list of supported contexts and UNSPECIFIED will be used in
11275   // the metadata.
11276   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
11277   types::BidirectionalPair<types::AudioContexts> metadata = {
11278           .sink = types::AudioContexts(types::LeAudioContextType::UNSPECIFIED),
11279           .source = types::AudioContexts()};
11280   EXPECT_CALL(mock_state_machine_,
11281               StartStream(_, types::LeAudioContextType::EMERGENCYALARM, metadata, _))
11282           .Times(1);
11283 
11284   LeAudioClient::Get()->GroupSetActive(group_id);
11285   SyncOnMainLoop();
11286 
11287   StartStreaming(AUDIO_USAGE_EMERGENCY, AUDIO_CONTENT_TYPE_UNKNOWN, group_id);
11288 
11289   SyncOnMainLoop();
11290   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
11291   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
11292 
11293   // Verify Data transfer on one audio source cis
11294   uint8_t cis_count_out = 1;
11295   uint8_t cis_count_in = 0;
11296   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
11297 }
11298 
TEST_F(UnicastTest,NotifyAboutGroupTunrnedIdleEnabled)11299 TEST_F(UnicastTest, NotifyAboutGroupTunrnedIdleEnabled) {
11300   const RawAddress test_address0 = GetTestAddress(0);
11301   int group_id = bluetooth::groups::kGroupUnknown;
11302 
11303   osi_property_set_bool(kNotifyUpperLayerAboutGroupBeingInIdleDuringCall, true);
11304 
11305   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
11306                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
11307                                 default_channel_cnt, 0x0004, false /*add_csis*/, true /*add_cas*/,
11308                                 true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
11309                                 0 /*rank*/);
11310   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11311               OnConnectionState(ConnectionState::CONNECTED, test_address0))
11312           .Times(1);
11313   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11314               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
11315           .WillOnce(DoAll(SaveArg<1>(&group_id)));
11316 
11317   ConnectLeAudio(test_address0);
11318   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
11319 
11320   // Start streaming
11321   uint8_t cis_count_out = 1;
11322   uint8_t cis_count_in = 0;
11323 
11324   LeAudioClient::Get()->SetInCall(true);
11325 
11326   // Audio sessions are started only when device gets active
11327   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
11328   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
11329   LeAudioClient::Get()->GroupSetActive(group_id);
11330   SyncOnMainLoop();
11331 
11332   StartStreaming(AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE, AUDIO_CONTENT_TYPE_UNKNOWN, group_id);
11333 
11334   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
11335   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
11336   SyncOnMainLoop();
11337 
11338   // Verify Data transfer on one audio source cis
11339   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
11340 
11341   // Release
11342 
11343   /* To be called twice
11344    * 1. GroupStatus::INACTIVE
11345    * 2. GroupStatus::TURNED_IDLE_DURING_CALL
11346    */
11347   EXPECT_CALL(mock_audio_hal_client_callbacks_, OnGroupStatus(group_id, _)).Times(2);
11348 
11349   EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop()).Times(1);
11350   EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(1);
11351   EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(1);
11352 
11353   do_in_main_thread(base::BindOnce(
11354           [](LeAudioClient* client) { client->GroupSetActive(bluetooth::groups::kGroupUnknown); },
11355           LeAudioClient::Get()));
11356 
11357   SyncOnMainLoop();
11358   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
11359 
11360   LeAudioClient::Get()->SetInCall(false);
11361   osi_property_set_bool(kNotifyUpperLayerAboutGroupBeingInIdleDuringCall, false);
11362 }
11363 
TEST_F(UnicastTest,NotifyAboutGroupTunrnedIdleDisabled)11364 TEST_F(UnicastTest, NotifyAboutGroupTunrnedIdleDisabled) {
11365   const RawAddress test_address0 = GetTestAddress(0);
11366   int group_id = bluetooth::groups::kGroupUnknown;
11367 
11368   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
11369                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
11370                                 default_channel_cnt, 0x0004, false /*add_csis*/, true /*add_cas*/,
11371                                 true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
11372                                 0 /*rank*/);
11373   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11374               OnConnectionState(ConnectionState::CONNECTED, test_address0))
11375           .Times(1);
11376   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11377               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
11378           .WillOnce(DoAll(SaveArg<1>(&group_id)));
11379 
11380   ConnectLeAudio(test_address0);
11381   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
11382 
11383   // Start streaming
11384   uint8_t cis_count_out = 1;
11385   uint8_t cis_count_in = 0;
11386 
11387   LeAudioClient::Get()->SetInCall(true);
11388 
11389   // Audio sessions are started only when device gets active
11390   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
11391   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
11392   LeAudioClient::Get()->GroupSetActive(group_id);
11393   SyncOnMainLoop();
11394 
11395   StartStreaming(AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE, AUDIO_CONTENT_TYPE_UNKNOWN, group_id);
11396 
11397   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
11398   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
11399   SyncOnMainLoop();
11400 
11401   // Verify Data transfer on one audio source cis
11402   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
11403 
11404   // Release
11405 
11406   /* To be called once only
11407    * 1. GroupStatus::INACTIVE
11408    */
11409   EXPECT_CALL(mock_audio_hal_client_callbacks_, OnGroupStatus(group_id, _)).Times(1);
11410 
11411   EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop()).Times(1);
11412   EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(1);
11413   EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(1);
11414 
11415   do_in_main_thread(base::BindOnce(
11416           [](LeAudioClient* client) { client->GroupSetActive(bluetooth::groups::kGroupUnknown); },
11417           LeAudioClient::Get()));
11418 
11419   SyncOnMainLoop();
11420   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
11421 
11422   LeAudioClient::Get()->SetInCall(false);
11423 }
11424 
TEST_F(UnicastTest,HandleDatabaseOutOfSync)11425 TEST_F(UnicastTest, HandleDatabaseOutOfSync) {
11426   const RawAddress test_address0 = GetTestAddress(0);
11427   int group_id = bluetooth::groups::kGroupUnknown;
11428 
11429   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
11430                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
11431                                 default_channel_cnt, 0x0004, false /*add_csis*/, true /*add_cas*/,
11432                                 true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
11433                                 0 /*rank*/);
11434   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11435               OnConnectionState(ConnectionState::CONNECTED, test_address0))
11436           .Times(1);
11437   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11438               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
11439           .WillOnce(DoAll(SaveArg<1>(&group_id)));
11440 
11441   ConnectLeAudio(test_address0);
11442   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
11443 
11444   SyncOnMainLoop();
11445   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
11446 
11447   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11448               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
11449           .Times(1);
11450   InjectDisconnectedEvent(1, GATT_CONN_TERMINATE_PEER_USER);
11451   SyncOnMainLoop();
11452   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
11453   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
11454 
11455   /* Simulate DATABASE OUT OF SYNC */
11456   ccc_stored_byte_val_ = 0x01;
11457   gatt_read_ctp_ccc_status_ = GATT_DATABASE_OUT_OF_SYNC;
11458 
11459   EXPECT_CALL(mock_gatt_queue_, WriteDescriptor(_, _, _, _, _, _)).Times(0);
11460   ON_CALL(mock_gatt_interface_, ServiceSearchRequest(_, _)).WillByDefault(Return());
11461   EXPECT_CALL(mock_gatt_interface_, ServiceSearchRequest(_, _));
11462 
11463   InjectConnectedEvent(test_address0, 1);
11464   SyncOnMainLoop();
11465   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
11466   Mock::VerifyAndClearExpectations(&mock_gatt_queue_);
11467 }
11468 
TEST_F(UnicastTest,TestRemoteDeviceKeepCccValues)11469 TEST_F(UnicastTest, TestRemoteDeviceKeepCccValues) {
11470   const RawAddress test_address0 = GetTestAddress(0);
11471   int group_id = bluetooth::groups::kGroupUnknown;
11472 
11473   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
11474                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
11475                                 default_channel_cnt, 0x0004, false /*add_csis*/, true /*add_cas*/,
11476                                 true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
11477                                 0 /*rank*/);
11478   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11479               OnConnectionState(ConnectionState::CONNECTED, test_address0))
11480           .Times(1);
11481   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11482               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
11483           .WillOnce(DoAll(SaveArg<1>(&group_id)));
11484 
11485   ConnectLeAudio(test_address0);
11486   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
11487 
11488   SyncOnMainLoop();
11489   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
11490 
11491   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11492               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
11493           .Times(1);
11494   InjectDisconnectedEvent(1, GATT_CONN_TERMINATE_PEER_USER);
11495   SyncOnMainLoop();
11496   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
11497   Mock::VerifyAndClearExpectations(&mock_gatt_queue_);
11498 
11499   /* Simulate remote cache is good */
11500   ccc_stored_byte_val_ = 0x01;
11501 
11502   EXPECT_CALL(mock_gatt_queue_, WriteDescriptor(_, _, _, _, _, _)).Times(0);
11503   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11504               OnConnectionState(ConnectionState::CONNECTED, test_address0))
11505           .Times(1);
11506 
11507   InjectConnectedEvent(test_address0, 1);
11508   SyncOnMainLoop();
11509   Mock::VerifyAndClearExpectations(&mock_gatt_queue_);
11510   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
11511 }
11512 
TEST_F(UnicastTest,TestRemoteDeviceForgetsCccValues)11513 TEST_F(UnicastTest, TestRemoteDeviceForgetsCccValues) {
11514   const RawAddress test_address0 = GetTestAddress(0);
11515   int group_id = bluetooth::groups::kGroupUnknown;
11516 
11517   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
11518                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
11519                                 default_channel_cnt, 0x0004, false /*add_csis*/, true /*add_cas*/,
11520                                 true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
11521                                 0 /*rank*/);
11522   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11523               OnConnectionState(ConnectionState::CONNECTED, test_address0))
11524           .Times(1);
11525   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11526               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
11527           .WillOnce(DoAll(SaveArg<1>(&group_id)));
11528 
11529   ConnectLeAudio(test_address0);
11530   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
11531 
11532   SyncOnMainLoop();
11533   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
11534 
11535   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11536               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
11537           .Times(1);
11538   InjectDisconnectedEvent(1, GATT_CONN_TERMINATE_PEER_USER);
11539   SyncOnMainLoop();
11540   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
11541   Mock::VerifyAndClearExpectations(&mock_gatt_queue_);
11542 
11543   /* Simulate remote cache is broken */
11544   ccc_stored_byte_val_ = 0;
11545   EXPECT_CALL(mock_gatt_queue_, WriteDescriptor(_, _, _, _, _, _)).Times(AtLeast(1));
11546   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11547               OnConnectionState(ConnectionState::CONNECTED, test_address0))
11548           .Times(1);
11549 
11550   InjectConnectedEvent(test_address0, 1);
11551   SyncOnMainLoop();
11552   Mock::VerifyAndClearExpectations(&mock_gatt_queue_);
11553   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
11554 }
11555 
TEST_F(UnicastTest,SpeakerStreamingTimeout)11556 TEST_F(UnicastTest, SpeakerStreamingTimeout) {
11557   const RawAddress test_address0 = GetTestAddress(0);
11558   int group_id = bluetooth::groups::kGroupUnknown;
11559 
11560   SetSampleDatabaseEarbudsValid(
11561           1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
11562           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
11563           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
11564           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
11565   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11566               OnConnectionState(ConnectionState::CONNECTED, test_address0))
11567           .Times(1);
11568   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11569               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
11570           .WillOnce(DoAll(SaveArg<1>(&group_id)));
11571 
11572   ConnectLeAudio(test_address0);
11573   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
11574 
11575   // Start streaming
11576   uint8_t cis_count_out = 1;
11577   uint8_t cis_count_in = 0;
11578 
11579   // Audio sessions are started only when device gets active
11580   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
11581   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
11582   LeAudioClient::Get()->GroupSetActive(group_id);
11583   SyncOnMainLoop();
11584 
11585   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
11586 
11587   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
11588   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
11589   SyncOnMainLoop();
11590 
11591   // Verify Data transfer on one audio source cis
11592   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
11593 
11594   auto group = streaming_groups.at(group_id);
11595   auto device = group->GetFirstActiveDevice();
11596 
11597   // Do not accept direct connect, but expect it to arrive.
11598   ON_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_DIRECT_CONNECTION, _)).WillByDefault(Return());
11599 
11600   EXPECT_CALL(mock_btm_interface_, AclDisconnectFromHandle(device->conn_id_, _)).Times(1);
11601   ON_CALL(mock_btm_interface_, AclDisconnectFromHandle(_, _))
11602           .WillByDefault([](uint16_t handle, tHCI_STATUS /*rs*/) {
11603             ASSERT_NE(handle, GATT_INVALID_CONN_ID);
11604             // Do nothing here now.
11605           });
11606 
11607   state_machine_callbacks_->OnStateTransitionTimeout(group_id);
11608   SyncOnMainLoop();
11609   ASSERT_EQ(device->GetConnectionState(), DeviceConnectState::DISCONNECTING_AND_RECOVER);
11610 
11611   InjectDisconnectedEvent(device->conn_id_, GATT_CONN_TERMINATE_LOCAL_HOST);
11612   SyncOnMainLoop();
11613 
11614   /* No assigned cises should remain when transition remains in IDLE state */
11615   ASSERT_NE(0lu, streaming_groups.count(group_id));
11616   ASSERT_EQ(0, static_cast<int>(group->cig.cises.size()));
11617   ASSERT_TRUE(device != nullptr);
11618   ASSERT_EQ(device->GetConnectionState(), DeviceConnectState::CONNECTING_AUTOCONNECT);
11619   Mock::VerifyAndClearExpectations(&mock_btm_interface_);
11620 }
11621 
TEST_F(UnicastTest,AddMemberToAllowListWhenOneDeviceConnected)11622 TEST_F(UnicastTest, AddMemberToAllowListWhenOneDeviceConnected) {
11623   uint8_t group_size = 2;
11624   int group_id = 2;
11625   int conn_id_dev_0 = 1;
11626   int conn_id_dev_1 = 2;
11627 
11628   /*Scenario to test
11629    * 1. Connect Device A and disconnect
11630    * 2. Connect Device B
11631    * 3. verify Device B is in the allow list with direct connect.
11632    */
11633   // Report working CSIS
11634   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
11635 
11636   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
11637           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
11638 
11639   // First earbud
11640   const RawAddress test_address0 = GetTestAddress(0);
11641   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
11642 
11643   ConnectCsisDevice(test_address0, conn_id_dev_0, codec_spec_conf::kLeAudioLocationFrontLeft,
11644                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
11645 
11646   SyncOnMainLoop();
11647 
11648   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, _)).Times(1);
11649   EXPECT_CALL(mock_gatt_interface_,
11650               Open(gatt_if, test_address0, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _))
11651           .Times(1);
11652 
11653   InjectDisconnectedEvent(conn_id_dev_0);
11654 
11655   SyncOnMainLoop();
11656   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
11657 
11658   // Second earbud
11659   const RawAddress test_address1 = GetTestAddress(1);
11660   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
11661 
11662   /* Do not connect first  device but expect Open will arrive.*/
11663   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, false)).Times(1);
11664   EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address0, BTM_BLE_DIRECT_CONNECTION, _))
11665           .Times(1);
11666   ON_CALL(mock_gatt_interface_, Open(_, test_address0, BTM_BLE_DIRECT_CONNECTION, _))
11667           .WillByDefault(Return());
11668 
11669   ConnectCsisDevice(test_address1, conn_id_dev_1, codec_spec_conf::kLeAudioLocationFrontRight,
11670                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
11671                     true /*connect_through_csis*/);
11672 
11673   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
11674 }
11675 
TEST_F(UnicastTest,ResetToDefaultReconnectionMode)11676 TEST_F(UnicastTest, ResetToDefaultReconnectionMode) {
11677   uint8_t group_size = 2;
11678   int group_id = 2;
11679   int conn_id_dev_0 = 1;
11680   int conn_id_dev_1 = 2;
11681 
11682   /*Scenario to test
11683    * 1. Connect Device A and disconnect
11684    * 2. Connect Device B
11685    * 3. verify Device B is in the allow list.
11686    * 4. Disconnect B device
11687    * 5, Verify A and B device are back in targeted announcement reconnection
11688    * mode
11689    */
11690   // Report working CSIS
11691   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
11692 
11693   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
11694           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
11695 
11696   // First earbud
11697   const RawAddress test_address0 = GetTestAddress(0);
11698   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
11699 
11700   ConnectCsisDevice(test_address0, conn_id_dev_0, codec_spec_conf::kLeAudioLocationFrontLeft,
11701                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
11702 
11703   SyncOnMainLoop();
11704 
11705   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, _)).Times(1);
11706   EXPECT_CALL(mock_gatt_interface_,
11707               Open(gatt_if, test_address0, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _))
11708           .Times(1);
11709 
11710   InjectDisconnectedEvent(conn_id_dev_0);
11711 
11712   SyncOnMainLoop();
11713   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
11714 
11715   // Second earbud
11716   const RawAddress test_address1 = GetTestAddress(1);
11717   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
11718 
11719   /* Verify first earbud will start doing direct connect first */
11720   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, false)).Times(1);
11721   ON_CALL(mock_gatt_interface_, Open(_, test_address0, BTM_BLE_DIRECT_CONNECTION, _))
11722           .WillByDefault(Return());
11723   EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address0, BTM_BLE_DIRECT_CONNECTION, _))
11724           .Times(1);
11725 
11726   ConnectCsisDevice(test_address1, conn_id_dev_1, codec_spec_conf::kLeAudioLocationFrontRight,
11727                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
11728                     true /*connect_through_csis*/);
11729 
11730   SyncOnMainLoop();
11731   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
11732 
11733   // Disconnect Device B, expect default reconnection mode for Device A.
11734   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, false)).Times(1);
11735   EXPECT_CALL(mock_gatt_interface_,
11736               Open(gatt_if, test_address0, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _))
11737           .Times(1);
11738   EXPECT_CALL(mock_gatt_interface_,
11739               Open(gatt_if, test_address1, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _))
11740           .Times(1);
11741   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address1, false)).Times(1);
11742 
11743   InjectDisconnectedEvent(conn_id_dev_1, GATT_CONN_TERMINATE_PEER_USER);
11744   SyncOnMainLoop();
11745 
11746   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
11747 }
11748 
TEST_F(UnicastTest,DisconnectAclBeforeGettingReadResponses)11749 TEST_F(UnicastTest, DisconnectAclBeforeGettingReadResponses) {
11750   uint8_t group_size = 2;
11751   int group_id = 2;
11752 
11753   // Report working CSIS
11754   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
11755 
11756   const RawAddress test_address0 = GetTestAddress(0);
11757   const RawAddress test_address1 = GetTestAddress(1);
11758 
11759   /* Due to imitated problems with GATT read operations (status != GATT_SUCCESS)
11760    * a CONNECTED state should not be propagated together with audio location
11761    */
11762   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11763               OnConnectionState(ConnectionState::CONNECTED, test_address0))
11764           .Times(0);
11765   EXPECT_CALL(
11766           mock_audio_hal_client_callbacks_,
11767           OnSinkAudioLocationAvailable(test_address0, codec_spec_conf::kLeAudioLocationFrontLeft))
11768           .Times(0);
11769 
11770   // First earbud initial connection
11771   SetSampleDatabaseEarbudsValid(1 /* conn_id */, test_address0,
11772                                 codec_spec_conf::kLeAudioLocationFrontLeft,
11773                                 codec_spec_conf::kLeAudioLocationFrontLeft, default_channel_cnt,
11774                                 default_channel_cnt, 0x0004, /* source sample freq 16khz */
11775                                 true,                        /*add_csis*/
11776                                 true,                        /*add_cas*/
11777                                 true,                        /*add_pacs*/
11778                                 true,                        /*add_ascs*/
11779                                 group_size, 1 /* rank */, GATT_INTERNAL_ERROR);
11780   groups[test_address0] = group_id;
11781   // by default indicate link as encrypted
11782   ON_CALL(mock_btm_interface_, BTM_IsEncrypted(test_address0, _))
11783           .WillByDefault(DoAll(Return(true)));
11784 
11785   EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address0, BTM_BLE_DIRECT_CONNECTION, _))
11786           .Times(1);
11787   /* When connected it will got to TA */
11788   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, _)).Times(1);
11789   EXPECT_CALL(mock_gatt_interface_,
11790               Open(gatt_if, test_address0, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _))
11791           .Times(1);
11792 
11793   do_in_main_thread(base::BindOnce(&LeAudioClient::Connect, base::Unretained(LeAudioClient::Get()),
11794                                    test_address0));
11795 
11796   SyncOnMainLoop();
11797   Mock::VerifyAndClearExpectations(&mock_btm_interface_);
11798   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
11799   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
11800   InjectGroupDeviceAdded(test_address0, group_id);
11801 
11802   // Second earbud initial connection
11803   EXPECT_CALL(
11804           mock_audio_hal_client_callbacks_,
11805           OnSinkAudioLocationAvailable(test_address1, codec_spec_conf::kLeAudioLocationFrontRight))
11806           .Times(1);
11807 
11808   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
11809   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
11810                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
11811                     true /*connect_through_csis*/);
11812 
11813   Mock::VerifyAndClearExpectations(&mock_btif_storage_);
11814 
11815   /* for Target announcements AutoConnect is always there, until
11816    * device is removed
11817    */
11818   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, false)).Times(0);
11819   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, false)).Times(0);
11820 
11821   // Verify grouping information
11822   std::vector<RawAddress> devs = LeAudioClient::Get()->GetGroupDevices(group_id);
11823   ASSERT_NE(std::find(devs.begin(), devs.end(), test_address0), devs.end());
11824   ASSERT_NE(std::find(devs.begin(), devs.end(), test_address1), devs.end());
11825 
11826   /* Remove default action on the direct connect */
11827   ON_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_DIRECT_CONNECTION, _)).WillByDefault(Return());
11828 
11829   /* Initiate disconnection with timeout reason, the possible reason why GATT
11830    * read attribute operation may be not handled
11831    */
11832   InjectDisconnectedEvent(1, GATT_CONN_TIMEOUT);
11833   SyncOnMainLoop();
11834 
11835   /* After reconnection a sink audio location callback with connection state
11836    * should be propagated.
11837    */
11838   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11839               OnConnectionState(ConnectionState::CONNECTED, test_address0))
11840           .Times(1);
11841   EXPECT_CALL(
11842           mock_audio_hal_client_callbacks_,
11843           OnSinkAudioLocationAvailable(test_address0, codec_spec_conf::kLeAudioLocationFrontLeft))
11844           .Times(1);
11845 
11846   /* Prepare valid GATT status responsing attributes */
11847   SetSampleDatabaseEarbudsValid(1 /* conn_id */, test_address0,
11848                                 codec_spec_conf::kLeAudioLocationFrontLeft,
11849                                 codec_spec_conf::kLeAudioLocationFrontLeft, default_channel_cnt,
11850                                 default_channel_cnt, 0x0004, /* source sample freq 16khz */
11851                                 true,                        /*add_csis*/
11852                                 true,                        /*add_cas*/
11853                                 true,                        /*add_pacs*/
11854                                 true,                        /*add_ascs*/
11855                                 group_size, 1 /* rank */);
11856 
11857   /* For background connect, test needs to Inject Connected Event */
11858   InjectConnectedEvent(test_address0, 1);
11859   SyncOnMainLoop();
11860 }
11861 
TEST_F(UnicastTest,GroupStreamStatus)11862 TEST_F(UnicastTest, GroupStreamStatus) {
11863   int group_id = bluetooth::groups::kGroupUnknown;
11864 
11865   InSequence s;
11866 
11867   /* Check if all states are properly notified */
11868   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11869               OnGroupStreamStatus(group_id, GroupStreamStatus::IDLE))
11870           .Times(1);
11871   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::IDLE);
11872 
11873   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11874               OnGroupStreamStatus(group_id, GroupStreamStatus::STREAMING))
11875           .Times(1);
11876   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::STREAMING);
11877 
11878   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11879               OnGroupStreamStatus(group_id, GroupStreamStatus::IDLE))
11880           .Times(1);
11881   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::RELEASING);
11882 
11883   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11884               OnGroupStreamStatus(group_id, GroupStreamStatus::STREAMING))
11885           .Times(1);
11886   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::STREAMING);
11887 
11888   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11889               OnGroupStreamStatus(group_id, GroupStreamStatus::IDLE))
11890           .Times(1);
11891   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::SUSPENDING);
11892 
11893   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11894               OnGroupStreamStatus(group_id, GroupStreamStatus::STREAMING))
11895           .Times(1);
11896   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::STREAMING);
11897 
11898   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11899               OnGroupStreamStatus(group_id, GroupStreamStatus::IDLE))
11900           .Times(1);
11901   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::SUSPENDED);
11902 
11903   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11904               OnGroupStreamStatus(group_id, GroupStreamStatus::STREAMING))
11905           .Times(1);
11906   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::STREAMING);
11907 
11908   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11909               OnGroupStreamStatus(group_id, GroupStreamStatus::IDLE))
11910           .Times(1);
11911   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::CONFIGURED_AUTONOMOUS);
11912 
11913   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11914               OnGroupStreamStatus(group_id, GroupStreamStatus::STREAMING))
11915           .Times(1);
11916   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::STREAMING);
11917 
11918   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11919               OnGroupStreamStatus(group_id, GroupStreamStatus::IDLE))
11920           .Times(1);
11921   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::CONFIGURED_BY_USER);
11922 
11923   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11924               OnGroupStreamStatus(group_id, GroupStreamStatus::STREAMING))
11925           .Times(1);
11926   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::STREAMING);
11927 
11928   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11929               OnGroupStreamStatus(group_id, GroupStreamStatus::IDLE))
11930           .Times(1);
11931   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::DESTROYED);
11932 
11933   /* Check if there are no resending of the same state */
11934   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::RELEASING);
11935   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::SUSPENDING);
11936   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::SUSPENDED);
11937   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::CONFIGURED_AUTONOMOUS);
11938   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::CONFIGURED_BY_USER);
11939   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::IDLE);
11940 
11941   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11942               OnGroupStreamStatus(group_id, GroupStreamStatus::STREAMING))
11943           .Times(1);
11944   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::STREAMING);
11945   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::STREAMING);
11946 }
11947 
TEST_F(UnicastTest,GroupStreamStatusManyGroups)11948 TEST_F(UnicastTest, GroupStreamStatusManyGroups) {
11949   uint8_t group_size = 2;
11950   int group_id_1 = 1;
11951   int group_id_2 = 2;
11952 
11953   // Report working CSIS
11954   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
11955 
11956   ON_CALL(mock_csis_client_module_, GetDesiredSize(_)).WillByDefault(Return(group_size));
11957 
11958   // First group - First earbud
11959   const RawAddress test_address0 = GetTestAddress(0);
11960   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
11961   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
11962                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id_1,
11963                     1 /* rank*/);
11964 
11965   // First group - Second earbud
11966   const RawAddress test_address1 = GetTestAddress(1);
11967   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
11968   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
11969                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id_1,
11970                     2 /* rank*/, true /*connect_through_csis*/);
11971 
11972   // Second group - First earbud
11973   const RawAddress test_address2 = GetTestAddress(2);
11974   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address2, true)).Times(1);
11975   ConnectCsisDevice(test_address2, 3 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
11976                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id_2,
11977                     1 /* rank*/);
11978 
11979   // Second group - Second earbud
11980   const RawAddress test_address3 = GetTestAddress(3);
11981   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address3, true)).Times(1);
11982   ConnectCsisDevice(test_address3, 4 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
11983                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id_2,
11984                     2 /* rank*/, true /*connect_through_csis*/);
11985 
11986   InSequence s;
11987 
11988   // Group 1 IDLE
11989   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11990               OnGroupStreamStatus(group_id_1, GroupStreamStatus::IDLE))
11991           .Times(1);
11992   state_machine_callbacks_->StatusReportCb(group_id_1, GroupStreamStatus::IDLE);
11993 
11994   // Group 2 IDLE
11995   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11996               OnGroupStreamStatus(group_id_2, GroupStreamStatus::IDLE))
11997           .Times(1);
11998   state_machine_callbacks_->StatusReportCb(group_id_2, GroupStreamStatus::IDLE);
11999 
12000   // Group 1 active and start streaming
12001   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12002               OnGroupStreamStatus(group_id_1, GroupStreamStatus::STREAMING))
12003           .Times(1);
12004   LeAudioClient::Get()->GroupSetActive(group_id_1);
12005   SyncOnMainLoop();
12006   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id_1);
12007   SyncOnMainLoop();
12008   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
12009 
12010   // Group 2 active
12011   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12012               OnGroupStreamStatus(group_id_1, GroupStreamStatus::IDLE))
12013           .Times(1);
12014   LeAudioClient::Get()->GroupSetActive(group_id_2);
12015   SyncOnMainLoop();
12016   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
12017 
12018   // Group 2 start streaming
12019   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12020               OnGroupStreamStatus(group_id_2, GroupStreamStatus::STREAMING))
12021           .Times(1);
12022   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id_2);
12023   SyncOnMainLoop();
12024   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
12025 }
12026 
TEST_F(UnicastTest,GroupStreamStatusResendAfterRemove)12027 TEST_F(UnicastTest, GroupStreamStatusResendAfterRemove) {
12028   uint8_t group_size = 2;
12029   int group_id = 1;
12030 
12031   // Report working CSIS
12032   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
12033 
12034   ON_CALL(mock_csis_client_module_, GetDesiredSize(_)).WillByDefault(Return(group_size));
12035 
12036   // First earbud
12037   const RawAddress test_address0 = GetTestAddress(0);
12038   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
12039   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
12040                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
12041 
12042   // Second earbud
12043   const RawAddress test_address1 = GetTestAddress(1);
12044   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
12045   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
12046                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
12047                     true /*connect_through_csis*/);
12048 
12049   Mock::VerifyAndClearExpectations(&mock_btif_storage_);
12050 
12051   InSequence s;
12052 
12053   // Activate group, start streaming and immediately stop
12054   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12055               OnGroupStreamStatus(group_id, GroupStreamStatus::STREAMING))
12056           .Times(1);
12057   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12058               OnGroupStreamStatus(group_id, GroupStreamStatus::IDLE))
12059           .Times(1);
12060   LeAudioClient::Get()->GroupSetActive(group_id);
12061   SyncOnMainLoop();
12062   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::STREAMING);
12063   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
12064 
12065   // No resend
12066   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12067               OnGroupStreamStatus(group_id, GroupStreamStatus::IDLE))
12068           .Times(0);
12069   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::IDLE);
12070 
12071   // No resend after removing only one device
12072   /*
12073    * StopStream will put calls on main_loop so to keep the correct order
12074    * of operations and to avoid races we put the test command on main_loop as
12075    * well.
12076    */
12077   do_in_main_thread(base::BindOnce(
12078           [](LeAudioClient* client, const RawAddress& test_address0) {
12079             client->RemoveDevice(test_address0);
12080           },
12081           LeAudioClient::Get(), test_address0));
12082   SyncOnMainLoop();
12083   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12084               OnGroupStreamStatus(group_id, GroupStreamStatus::IDLE))
12085           .Times(0);
12086   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::IDLE);
12087   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
12088 
12089   // Resend after removing last device
12090   /*
12091    * StopStream will put calls on main_loop so to keep the correct order
12092    * of operations and to avoid races we put the test command on main_loop as
12093    * well.
12094    */
12095   do_in_main_thread(base::BindOnce(
12096           [](LeAudioClient* client, const RawAddress& test_address1) {
12097             client->RemoveDevice(test_address1);
12098           },
12099           LeAudioClient::Get(), test_address1));
12100   SyncOnMainLoop();
12101   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12102               OnGroupStreamStatus(group_id, GroupStreamStatus::IDLE))
12103           .Times(1);
12104   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::IDLE);
12105   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
12106 }
12107 
TEST_F(UnicastTestHandoverMode,SetSinkMonitorModeWhileUnicastIsActive)12108 TEST_F(UnicastTestHandoverMode, SetSinkMonitorModeWhileUnicastIsActive) {
12109   uint8_t group_size = 2;
12110   int group_id = 2;
12111 
12112   // Report working CSIS
12113   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
12114 
12115   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
12116           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
12117 
12118   // First earbud
12119   const RawAddress test_address0 = GetTestAddress(0);
12120   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
12121   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
12122                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
12123 
12124   // Second earbud
12125   const RawAddress test_address1 = GetTestAddress(1);
12126   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
12127   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
12128                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
12129                     true /*connect_through_csis*/);
12130 
12131   // Start streaming
12132   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
12133   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
12134   LeAudioClient::Get()->GroupSetActive(group_id);
12135   SyncOnMainLoop();
12136 
12137   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
12138 
12139   StartStreaming(AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_CONTENT_TYPE_SPEECH, group_id);
12140 
12141   SyncOnMainLoop();
12142   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
12143   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
12144 
12145   // Verify Data transfer on two peer sinks and one source
12146   uint8_t cis_count_out = 2;
12147   uint8_t cis_count_in = 2;
12148   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 40);
12149 
12150   // Imitate activation of monitor mode
12151   do_in_main_thread(base::BindOnce(
12152           &LeAudioClient::SetUnicastMonitorMode, base::Unretained(LeAudioClient::Get()),
12153           bluetooth::le_audio::types::kLeAudioDirectionSink, true /* enable */));
12154 
12155   ASSERT_NE(0lu, streaming_groups.count(group_id));
12156   auto group = streaming_groups.at(group_id);
12157 
12158   // Stop streaming and expect Service to be informed about straming suspension
12159   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12160               OnUnicastMonitorModeStatus(bluetooth::le_audio::types::kLeAudioDirectionSink,
12161                                          UnicastMonitorModeStatus::STREAMING_SUSPENDED))
12162           .Times(1);
12163 
12164   // Stop
12165   StopStreaming(group_id, true);
12166 
12167   // Check if cache configuration is still present
12168   ASSERT_TRUE(group->GetCachedConfiguration(types::LeAudioContextType::CONVERSATIONAL)
12169                       ->confs.get(le_audio::types::kLeAudioDirectionSink)
12170                       .size());
12171   ASSERT_TRUE(group->GetCachedConfiguration(types::LeAudioContextType::CONVERSATIONAL)
12172                       ->confs.get(le_audio::types::kLeAudioDirectionSource)
12173                       .size());
12174 
12175   // Release, Sink HAL client should remain in monitor mode
12176   EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop()).Times(1);
12177   EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(1);
12178   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Stop()).Times(0);
12179   EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(0);
12180   LeAudioClient::Get()->GroupSetActive(bluetooth::groups::kGroupUnknown);
12181   SyncOnMainLoop();
12182 
12183   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
12184   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
12185   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
12186 
12187   // Re-initialize mock for destroyed hal client
12188   RegisterSourceHalClientMock();
12189 
12190   // Setting group inactive, shall not change cached configuration
12191   ASSERT_TRUE(group->GetCachedConfiguration(types::LeAudioContextType::CONVERSATIONAL)
12192                       ->confs.get(le_audio::types::kLeAudioDirectionSink)
12193                       .size());
12194   ASSERT_TRUE(group->GetCachedConfiguration(types::LeAudioContextType::CONVERSATIONAL)
12195                       ->confs.get(le_audio::types::kLeAudioDirectionSource)
12196                       .size());
12197 
12198   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12199               OnUnicastMonitorModeStatus(bluetooth::le_audio::types::kLeAudioDirectionSink,
12200                                          UnicastMonitorModeStatus::STREAMING_REQUESTED))
12201           .Times(1);
12202 
12203   // Start streaming to trigger next group going to IDLE state
12204   LocalAudioSinkResume();
12205 
12206   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
12207   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
12208   LeAudioClient::Get()->GroupSetActive(group_id);
12209   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
12210   SyncOnMainLoop();
12211 
12212   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
12213 
12214   StartStreaming(AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_CONTENT_TYPE_SPEECH, group_id);
12215   SyncOnMainLoop();
12216   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
12217 
12218   // Stop streaming and expect Service to be informed about straming suspension
12219   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12220               OnUnicastMonitorModeStatus(bluetooth::le_audio::types::kLeAudioDirectionSink,
12221                                          UnicastMonitorModeStatus::STREAMING_SUSPENDED))
12222           .Times(1);
12223 
12224   // Stop
12225   StopStreaming(group_id, true);
12226 
12227   // Release, Sink HAL client should remain in monitor mode
12228   EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop()).Times(1);
12229   EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(1);
12230   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Stop()).Times(0);
12231   EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(0);
12232   LeAudioClient::Get()->GroupSetActive(bluetooth::groups::kGroupUnknown);
12233   SyncOnMainLoop();
12234 
12235   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
12236   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
12237   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
12238 
12239   // De-activate monitoring mode
12240   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Stop()).Times(1);
12241   EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(1);
12242   do_in_main_thread(base::BindOnce(
12243           &LeAudioClient::SetUnicastMonitorMode, base::Unretained(LeAudioClient::Get()),
12244           bluetooth::le_audio::types::kLeAudioDirectionSink, false /* enable */));
12245   SyncOnMainLoop();
12246   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
12247 }
12248 
TEST_F(UnicastTestHandoverMode,SetSinkMonitorModeWhileUnicastIsInactive)12249 TEST_F(UnicastTestHandoverMode, SetSinkMonitorModeWhileUnicastIsInactive) {
12250   uint8_t group_size = 2;
12251   int group_id = 2;
12252 
12253   // Imitate activation of monitor mode
12254   do_in_main_thread(base::BindOnce(
12255           &LeAudioClient::SetUnicastMonitorMode, base::Unretained(LeAudioClient::Get()),
12256           bluetooth::le_audio::types::kLeAudioDirectionSink, true /* enable */));
12257 
12258   // Report working CSIS
12259   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
12260 
12261   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
12262           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
12263 
12264   // First earbud
12265   const RawAddress test_address0 = GetTestAddress(0);
12266   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
12267   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
12268                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
12269 
12270   // Second earbud
12271   const RawAddress test_address1 = GetTestAddress(1);
12272   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
12273   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
12274                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
12275                     true /*connect_through_csis*/);
12276 
12277   // Start streaming
12278   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
12279   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
12280   LeAudioClient::Get()->GroupSetActive(group_id);
12281   SyncOnMainLoop();
12282 
12283   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
12284 
12285   // Expect no streaming request on stream resume when group is already active
12286   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12287               OnUnicastMonitorModeStatus(bluetooth::le_audio::types::kLeAudioDirectionSink,
12288                                          UnicastMonitorModeStatus::STREAMING_REQUESTED))
12289           .Times(0);
12290 
12291   StartStreaming(AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_CONTENT_TYPE_SPEECH, group_id);
12292 
12293   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
12294   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
12295   SyncOnMainLoop();
12296 
12297   // Verify Data transfer on two peer sinks and one source
12298   uint8_t cis_count_out = 2;
12299   uint8_t cis_count_in = 2;
12300   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 40);
12301 
12302   ASSERT_NE(0lu, streaming_groups.count(group_id));
12303   auto group = streaming_groups.at(group_id);
12304 
12305   // Stop streaming and expect Service to be informed about straming suspension
12306   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12307               OnUnicastMonitorModeStatus(bluetooth::le_audio::types::kLeAudioDirectionSink,
12308                                          UnicastMonitorModeStatus::STREAMING_SUSPENDED))
12309           .Times(1);
12310 
12311   // Stop
12312   StopStreaming(group_id, true);
12313 
12314   // Check if cache configuration is still present
12315   ASSERT_TRUE(group->GetCachedConfiguration(types::LeAudioContextType::CONVERSATIONAL)
12316                       ->confs.get(le_audio::types::kLeAudioDirectionSink)
12317                       .size());
12318   ASSERT_TRUE(group->GetCachedConfiguration(types::LeAudioContextType::CONVERSATIONAL)
12319                       ->confs.get(le_audio::types::kLeAudioDirectionSource)
12320                       .size());
12321 
12322   // Release, Sink HAL client should remain in monitor mode
12323   EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop()).Times(1);
12324   EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(1);
12325   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Stop()).Times(0);
12326   EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(0);
12327   LeAudioClient::Get()->GroupSetActive(bluetooth::groups::kGroupUnknown);
12328   SyncOnMainLoop();
12329 
12330   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
12331   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
12332   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
12333 
12334   // Setting group inactive, shall not change cached configuration
12335   ASSERT_TRUE(group->GetCachedConfiguration(types::LeAudioContextType::CONVERSATIONAL)
12336                       ->confs.get(le_audio::types::kLeAudioDirectionSink)
12337                       .size());
12338   ASSERT_TRUE(group->GetCachedConfiguration(types::LeAudioContextType::CONVERSATIONAL)
12339                       ->confs.get(le_audio::types::kLeAudioDirectionSource)
12340                       .size());
12341 }
12342 
TEST_F(UnicastTestHandoverMode,ClearSinkMonitorModeWhileUnicastIsActive)12343 TEST_F(UnicastTestHandoverMode, ClearSinkMonitorModeWhileUnicastIsActive) {
12344   uint8_t group_size = 2;
12345   int group_id = 2;
12346 
12347   // Imitate activation of monitor mode
12348   do_in_main_thread(base::BindOnce(
12349           &LeAudioClient::SetUnicastMonitorMode, base::Unretained(LeAudioClient::Get()),
12350           bluetooth::le_audio::types::kLeAudioDirectionSink, true /* enable */));
12351 
12352   // Report working CSIS
12353   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
12354 
12355   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
12356           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
12357 
12358   // First earbud
12359   const RawAddress test_address0 = GetTestAddress(0);
12360   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
12361   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
12362                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
12363 
12364   // Second earbud
12365   const RawAddress test_address1 = GetTestAddress(1);
12366   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
12367   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
12368                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
12369                     true /*connect_through_csis*/);
12370 
12371   // Start streaming
12372   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
12373   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
12374   LeAudioClient::Get()->GroupSetActive(group_id);
12375   SyncOnMainLoop();
12376 
12377   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
12378 
12379   // Expect no streaming request on stream resume when group is already active
12380   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12381               OnUnicastMonitorModeStatus(bluetooth::le_audio::types::kLeAudioDirectionSink,
12382                                          UnicastMonitorModeStatus::STREAMING_REQUESTED))
12383           .Times(0);
12384 
12385   StartStreaming(AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_CONTENT_TYPE_SPEECH, group_id);
12386 
12387   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
12388   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
12389   SyncOnMainLoop();
12390 
12391   // Verify Data transfer on two peer sinks and one source
12392   uint8_t cis_count_out = 2;
12393   uint8_t cis_count_in = 2;
12394   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 40);
12395 
12396   ASSERT_NE(0lu, streaming_groups.count(group_id));
12397   auto group = streaming_groups.at(group_id);
12398 
12399   // De-activate monitoring mode
12400   do_in_main_thread(base::BindOnce(
12401           &LeAudioClient::SetUnicastMonitorMode, base::Unretained(LeAudioClient::Get()),
12402           bluetooth::le_audio::types::kLeAudioDirectionSink, false /* enable */));
12403 
12404   // Stop
12405   StopStreaming(group_id, true);
12406   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
12407 
12408   // Check if cache configuration is still present
12409   ASSERT_TRUE(group->GetCachedConfiguration(types::LeAudioContextType::CONVERSATIONAL)
12410                       ->confs.get(le_audio::types::kLeAudioDirectionSink)
12411                       .size());
12412   ASSERT_TRUE(group->GetCachedConfiguration(types::LeAudioContextType::CONVERSATIONAL)
12413                       ->confs.get(le_audio::types::kLeAudioDirectionSource)
12414                       .size());
12415 
12416   // Release of sink and source hals due to de-activating monitor mode
12417   EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop()).Times(1);
12418   EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(1);
12419   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Stop()).Times(1);
12420   EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(1);
12421   LeAudioClient::Get()->GroupSetActive(bluetooth::groups::kGroupUnknown);
12422   SyncOnMainLoop();
12423 
12424   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
12425   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
12426 
12427   // Setting group inactive, shall not change cached configuration
12428   ASSERT_TRUE(group->GetCachedConfiguration(types::LeAudioContextType::CONVERSATIONAL)
12429                       ->confs.get(le_audio::types::kLeAudioDirectionSink)
12430                       .size());
12431   ASSERT_TRUE(group->GetCachedConfiguration(types::LeAudioContextType::CONVERSATIONAL)
12432                       ->confs.get(le_audio::types::kLeAudioDirectionSource)
12433                       .size());
12434 }
12435 
TEST_F(UnicastTestHandoverMode,SetAndClearSinkMonitorModeWhileUnicastIsInactive)12436 TEST_F(UnicastTestHandoverMode, SetAndClearSinkMonitorModeWhileUnicastIsInactive) {
12437   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(0);
12438   EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop()).Times(0);
12439   EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(0);
12440   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(0);
12441   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Stop()).Times(0);
12442   EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(0);
12443 
12444   // Imitate activation of monitor mode
12445   do_in_main_thread(base::BindOnce(
12446           &LeAudioClient::SetUnicastMonitorMode, base::Unretained(LeAudioClient::Get()),
12447           bluetooth::le_audio::types::kLeAudioDirectionSink, true /* enable */));
12448   do_in_main_thread(base::BindOnce(
12449           &LeAudioClient::SetUnicastMonitorMode, base::Unretained(LeAudioClient::Get()),
12450           bluetooth::le_audio::types::kLeAudioDirectionSink, false /* enable */));
12451 
12452   SyncOnMainLoop();
12453 
12454   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
12455   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
12456 }
12457 
TEST_F(UnicastTestHandoverMode,SetSourceMonitorModeWhileUnicastIsInactive)12458 TEST_F(UnicastTestHandoverMode, SetSourceMonitorModeWhileUnicastIsInactive) {
12459   /* Enabling monitor mode for source while group is not active should result in
12460    * sending STREAMING_SUSPENDED notification.
12461    */
12462   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12463               OnUnicastMonitorModeStatus(bluetooth::le_audio::types::kLeAudioDirectionSource,
12464                                          UnicastMonitorModeStatus::STREAMING_SUSPENDED))
12465           .Times(1);
12466 
12467   // Imitate activation of monitor mode
12468   do_in_main_thread(base::BindOnce(
12469           &LeAudioClient::SetUnicastMonitorMode, base::Unretained(LeAudioClient::Get()),
12470           bluetooth::le_audio::types::kLeAudioDirectionSource, true /* enable */));
12471   SyncOnMainLoop();
12472   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
12473 }
12474 
TEST_F(UnicastTestHandoverMode,SetTwiceSourceMonitorModeWhileUnicastIsInactive)12475 TEST_F(UnicastTestHandoverMode, SetTwiceSourceMonitorModeWhileUnicastIsInactive) {
12476   /* Enabling monitor mode for source while group is not active should result in
12477    * sending STREAMING_SUSPENDED notification.
12478    */
12479   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12480               OnUnicastMonitorModeStatus(bluetooth::le_audio::types::kLeAudioDirectionSource,
12481                                          UnicastMonitorModeStatus::STREAMING_SUSPENDED))
12482           .Times(1);
12483 
12484   // Imitate activation of monitor mode
12485   do_in_main_thread(base::BindOnce(
12486           &LeAudioClient::SetUnicastMonitorMode, base::Unretained(LeAudioClient::Get()),
12487           bluetooth::le_audio::types::kLeAudioDirectionSource, true /* enable */));
12488   // Imitate second activation of monitor mode - should not be notified
12489   do_in_main_thread(base::BindOnce(
12490           &LeAudioClient::SetUnicastMonitorMode, base::Unretained(LeAudioClient::Get()),
12491           bluetooth::le_audio::types::kLeAudioDirectionSource, true /* enable */));
12492   SyncOnMainLoop();
12493   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
12494 }
12495 
TEST_F(UnicastTestHandoverMode,SetSourceMonitorModeWhileUnicastIsNotStreaming)12496 TEST_F(UnicastTestHandoverMode, SetSourceMonitorModeWhileUnicastIsNotStreaming) {
12497   int group_id = 2;
12498 
12499   LeAudioClient::Get()->GroupSetActive(group_id);
12500 
12501   /* Enabling monitor mode for source while group is not active should result in
12502    * sending STREAMING_SUSPENDED notification.
12503    */
12504   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12505               OnUnicastMonitorModeStatus(bluetooth::le_audio::types::kLeAudioDirectionSource,
12506                                          UnicastMonitorModeStatus::STREAMING_SUSPENDED))
12507           .Times(1);
12508 
12509   // Imitate activation of monitor mode
12510   do_in_main_thread(base::BindOnce(
12511           &LeAudioClient::SetUnicastMonitorMode, base::Unretained(LeAudioClient::Get()),
12512           bluetooth::le_audio::types::kLeAudioDirectionSource, true /* enable */));
12513   SyncOnMainLoop();
12514   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
12515 }
12516 
TEST_F(UnicastTestHandoverMode,SetSourceMonitorModeWhileUnicastIsActive)12517 TEST_F(UnicastTestHandoverMode, SetSourceMonitorModeWhileUnicastIsActive) {
12518   uint8_t group_size = 2;
12519   int group_id = 2;
12520 
12521   // Report working CSIS
12522   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
12523 
12524   // First earbud
12525   const RawAddress test_address0 = GetTestAddress(0);
12526   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
12527   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
12528                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
12529 
12530   // Second earbud
12531   const RawAddress test_address1 = GetTestAddress(1);
12532   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
12533   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
12534                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
12535                     true /*connect_through_csis*/);
12536 
12537   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
12538           .WillByDefault(Invoke([&](int /*group_id*/) { return 2; }));
12539 
12540   // Start streaming
12541   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
12542   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
12543   LeAudioClient::Get()->GroupSetActive(group_id);
12544   SyncOnMainLoop();
12545 
12546   StartStreaming(AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_CONTENT_TYPE_SPEECH, group_id);
12547 
12548   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
12549   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
12550   SyncOnMainLoop();
12551 
12552   // Verify Data transfer on two peer sinks and one source
12553   uint8_t cis_count_out = 2;
12554   uint8_t cis_count_in = 2;
12555   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 40);
12556 
12557   /* Enabling monitor mode for source while stream is active should result in
12558    * sending STREAMING notification.
12559    */
12560   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12561               OnUnicastMonitorModeStatus(bluetooth::le_audio::types::kLeAudioDirectionSource,
12562                                          UnicastMonitorModeStatus::STREAMING))
12563           .Times(1);
12564 
12565   // Imitate activation of monitor mode
12566   do_in_main_thread(base::BindOnce(
12567           &LeAudioClient::SetUnicastMonitorMode, base::Unretained(LeAudioClient::Get()),
12568           bluetooth::le_audio::types::kLeAudioDirectionSource, true /* enable */));
12569   SyncOnMainLoop();
12570   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
12571 
12572   ASSERT_NE(0lu, streaming_groups.count(group_id));
12573   auto group = streaming_groups.at(group_id);
12574 
12575   // Stop streaming and expect Service to be informed about straming suspension
12576   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12577               OnUnicastMonitorModeStatus(bluetooth::le_audio::types::kLeAudioDirectionSource,
12578                                          UnicastMonitorModeStatus::STREAMING_SUSPENDED))
12579           .Times(1);
12580 
12581   // Stop
12582   StopStreaming(group_id, true);
12583 
12584   // Check if cache configuration is still present
12585   ASSERT_TRUE(group->GetCachedConfiguration(types::LeAudioContextType::CONVERSATIONAL)
12586                       ->confs.get(le_audio::types::kLeAudioDirectionSink)
12587                       .size());
12588   ASSERT_TRUE(group->GetCachedConfiguration(types::LeAudioContextType::CONVERSATIONAL)
12589                       ->confs.get(le_audio::types::kLeAudioDirectionSource)
12590                       .size());
12591 
12592   // Both Sink and Source HAL clients should be stopped
12593   EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop()).Times(1);
12594   EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(1);
12595   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Stop()).Times(1);
12596   EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(1);
12597   LeAudioClient::Get()->GroupSetActive(bluetooth::groups::kGroupUnknown);
12598   SyncOnMainLoop();
12599 
12600   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
12601   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
12602   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
12603 
12604   // Re-initialize mock for destroyed hal client
12605   RegisterSourceHalClientMock();
12606   RegisterSinkHalClientMock();
12607 
12608   // Setting group inactive, shall not change cached configuration
12609   ASSERT_TRUE(group->GetCachedConfiguration(types::LeAudioContextType::CONVERSATIONAL)
12610                       ->confs.get(le_audio::types::kLeAudioDirectionSink)
12611                       .size());
12612   ASSERT_TRUE(group->GetCachedConfiguration(types::LeAudioContextType::CONVERSATIONAL)
12613                       ->confs.get(le_audio::types::kLeAudioDirectionSource)
12614                       .size());
12615 
12616   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12617               OnUnicastMonitorModeStatus(bluetooth::le_audio::types::kLeAudioDirectionSource,
12618                                          UnicastMonitorModeStatus::STREAMING_REQUESTED))
12619           .Times(1);
12620 
12621   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
12622   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
12623   LeAudioClient::Get()->GroupSetActive(group_id);
12624 
12625   // Start streaming to trigger next group going to IDLE state
12626   StartStreaming(AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_CONTENT_TYPE_SPEECH, group_id);
12627   SyncOnMainLoop();
12628 
12629   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
12630   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
12631   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
12632 
12633   // Stop streaming and expect Service to be informed about straming suspension
12634   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12635               OnUnicastMonitorModeStatus(bluetooth::le_audio::types::kLeAudioDirectionSource,
12636                                          UnicastMonitorModeStatus::STREAMING_SUSPENDED))
12637           .Times(1);
12638 
12639   // Stop
12640   StopStreaming(group_id, true);
12641 
12642   // Both Sink and Source HAL clients should be stopped
12643   EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop()).Times(1);
12644   EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(1);
12645   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Stop()).Times(1);
12646   EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(1);
12647   LeAudioClient::Get()->GroupSetActive(bluetooth::groups::kGroupUnknown);
12648   SyncOnMainLoop();
12649 
12650   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
12651   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
12652   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
12653 
12654   // De-activate monitoring mode
12655   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12656               OnUnicastMonitorModeStatus(bluetooth::le_audio::types::kLeAudioDirectionSource,
12657                                          UnicastMonitorModeStatus::STREAMING_SUSPENDED))
12658           .Times(0);
12659 
12660   do_in_main_thread(base::BindOnce(
12661           &LeAudioClient::SetUnicastMonitorMode, base::Unretained(LeAudioClient::Get()),
12662           bluetooth::le_audio::types::kLeAudioDirectionSink, false /* enable */));
12663 }
12664 
TEST_F(UnicastTestHandoverMode,SetAllowedContextMask)12665 TEST_F(UnicastTestHandoverMode, SetAllowedContextMask) {
12666   const RawAddress test_address0 = GetTestAddress(0);
12667   int group_id = bluetooth::groups::kGroupUnknown;
12668 
12669   available_snk_context_types_ =
12670           (types::LeAudioContextType::RINGTONE | types::LeAudioContextType::CONVERSATIONAL |
12671            types::LeAudioContextType::UNSPECIFIED | types::LeAudioContextType::MEDIA |
12672            types::LeAudioContextType::SOUNDEFFECTS)
12673                   .value();
12674   available_src_context_types_ = available_snk_context_types_;
12675   supported_snk_context_types_ = types::kLeAudioContextAllTypes.value();
12676   supported_src_context_types_ =
12677           (types::kLeAudioContextAllRemoteSource | types::LeAudioContextType::UNSPECIFIED).value();
12678   /* Don't allow SOUNDEFFECTS context type to be streamed */
12679   int allowed_context_types =
12680           (types::LeAudioContextType::RINGTONE | types::LeAudioContextType::CONVERSATIONAL |
12681            types::LeAudioContextType::UNSPECIFIED | types::LeAudioContextType::MEDIA)
12682                   .value();
12683 
12684   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
12685                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
12686                                 default_channel_cnt, 0x0004, false /*add_csis*/, true /*add_cas*/,
12687                                 true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
12688                                 0 /*rank*/);
12689   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12690               OnConnectionState(ConnectionState::CONNECTED, test_address0))
12691           .Times(1);
12692   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12693               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
12694           .WillOnce(DoAll(SaveArg<1>(&group_id)));
12695 
12696   ConnectLeAudio(test_address0);
12697   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
12698 
12699   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
12700   EXPECT_CALL(mock_state_machine_, StartStream(_, types::LeAudioContextType::SOUNDEFFECTS, _, _))
12701           .Times(0);
12702 
12703   LeAudioClient::Get()->GroupSetActive(group_id);
12704   SyncOnMainLoop();
12705 
12706   /* Set the same allowed context mask for sink and source */
12707   LeAudioClient::Get()->SetGroupAllowedContextMask(group_id, allowed_context_types,
12708                                                    allowed_context_types);
12709 
12710   StartStreaming(AUDIO_USAGE_ASSISTANCE_SONIFICATION, AUDIO_CONTENT_TYPE_UNKNOWN, group_id,
12711                  AUDIO_SOURCE_INVALID, false, false);
12712 
12713   SyncOnMainLoop();
12714   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
12715   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
12716 }
12717 
TEST_F(UnicastTest,NoContextvalidateStreamingRequest)12718 TEST_F(UnicastTest, NoContextvalidateStreamingRequest) {
12719   com::android::bluetooth::flags::provider_->leaudio_no_context_validate_streaming_request(true);
12720 
12721   const RawAddress test_address0 = GetTestAddress(0);
12722   int group_id = bluetooth::groups::kGroupUnknown;
12723 
12724   available_snk_context_types_ =
12725           (types::LeAudioContextType::RINGTONE | types::LeAudioContextType::CONVERSATIONAL |
12726            types::LeAudioContextType::UNSPECIFIED | types::LeAudioContextType::MEDIA)
12727                   .value();
12728   available_src_context_types_ = available_snk_context_types_;
12729   supported_snk_context_types_ = types::kLeAudioContextAllTypes.value();
12730   supported_src_context_types_ =
12731           (types::kLeAudioContextAllRemoteSource | types::LeAudioContextType::UNSPECIFIED).value();
12732 
12733   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
12734                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
12735                                 default_channel_cnt, 0x0004, false /*add_csis*/, true /*add_cas*/,
12736                                 true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
12737                                 0 /*rank*/);
12738   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12739               OnConnectionState(ConnectionState::CONNECTED, test_address0))
12740           .Times(1);
12741   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12742               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
12743           .WillOnce(DoAll(SaveArg<1>(&group_id)));
12744 
12745   ConnectLeAudio(test_address0);
12746   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
12747 
12748   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
12749   types::BidirectionalPair<types::AudioContexts> metadata = {.sink = types::AudioContexts(),
12750                                                              .source = types::AudioContexts()};
12751   EXPECT_CALL(mock_state_machine_,
12752               StartStream(_, types::LeAudioContextType::SOUNDEFFECTS, metadata, _))
12753           .Times(0);
12754 
12755   LeAudioClient::Get()->GroupSetActive(group_id);
12756 
12757   // Imitate activation of monitor mode
12758   do_in_main_thread(base::BindOnce(
12759           &LeAudioClient::SetUnicastMonitorMode, base::Unretained(LeAudioClient::Get()),
12760           bluetooth::le_audio::types::kLeAudioDirectionSource, true /* enable */));
12761   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
12762   SyncOnMainLoop();
12763 
12764   // Stop streaming and expect Service to be informed about streaming suspension
12765   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12766               OnUnicastMonitorModeStatus(
12767                       bluetooth::le_audio::types::kLeAudioDirectionSource,
12768                       UnicastMonitorModeStatus::STREAMING_REQUESTED_NO_CONTEXT_VALIDATE))
12769           .Times(1);
12770 
12771   StartStreaming(AUDIO_USAGE_ASSISTANCE_SONIFICATION, AUDIO_CONTENT_TYPE_UNKNOWN, group_id,
12772                  AUDIO_SOURCE_INVALID, false, false);
12773 
12774   SyncOnMainLoop();
12775   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
12776   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
12777 }
12778 
TEST_F(UnicastTest,CodecFrameBlocks2)12779 TEST_F(UnicastTest, CodecFrameBlocks2) {
12780   auto const max_codec_frames_per_sdu = 2;
12781   uint32_t data_len = 1920;
12782 
12783   // Register a on-the-fly hook for codec interface mock mutation to prepare the
12784   // codec mock for encoding
12785   std::list<MockCodecInterface*> codec_mocks;
12786   MockCodecInterface::RegisterMockInstanceHook([&](MockCodecInterface* mock, bool is_destroyed) {
12787     if (is_destroyed) {
12788       log::debug("Codec Interface Destroyed: {}", std::format_ptr(mock));
12789       codec_mocks.remove(mock);
12790     } else {
12791       log::debug("Codec Interface Created: {}", std::format_ptr(mock));
12792       ON_CALL(*mock, GetNumOfSamplesPerChannel()).WillByDefault(Return(960));
12793       ON_CALL(*mock, GetNumOfBytesPerSample()).WillByDefault(Return(2));  // 16bits samples
12794       ON_CALL(*mock, Encode(_, _, _, _, _))
12795               .WillByDefault(Return(CodecInterface::Status::STATUS_OK));
12796       codec_mocks.push_back(mock);
12797     }
12798   });
12799 
12800   // Add a frame block PAC passing provider
12801   bool is_fb2_passed_as_requirement = false;
12802   ON_CALL(*mock_codec_manager_, GetCodecConfig)
12803           .WillByDefault(Invoke(
12804                   [&](const bluetooth::le_audio::CodecManager::UnicastConfigurationRequirements&
12805                               requirements,
12806                       bluetooth::le_audio::CodecManager::UnicastConfigurationProvider provider) {
12807                     auto filtered = *bluetooth::le_audio::AudioSetConfigurationProvider::Get()
12808                                              ->GetConfigurations(requirements.audio_context_type);
12809                     // Filter out the dual bidir SWB configurations
12810                     if (!bluetooth::le_audio::CodecManager::GetInstance()
12811                                  ->IsDualBiDirSwbSupported()) {
12812                       filtered.erase(
12813                               std::remove_if(filtered.begin(), filtered.end(),
12814                                              [](auto const& el) {
12815                                                if (el->confs.source.empty()) {
12816                                                  return false;
12817                                                }
12818                                                return AudioSetConfigurationProvider::Get()
12819                                                        ->CheckConfigurationIsDualBiDirSwb(*el);
12820                                              }),
12821                               filtered.end());
12822                     }
12823                     auto cfg = provider(requirements, &filtered);
12824                     if (cfg == nullptr) {
12825                       return std::unique_ptr<
12826                               bluetooth::le_audio::set_configurations::AudioSetConfiguration>(
12827                               nullptr);
12828                     }
12829 
12830                     if (requirements.sink_pacs.has_value()) {
12831                       for (auto const& rec : requirements.sink_pacs.value()) {
12832                         auto caps = rec.codec_spec_caps.GetAsCoreCodecCapabilities();
12833                         if (caps.HasSupportedMaxCodecFramesPerSdu()) {
12834                           if (caps.supported_max_codec_frames_per_sdu.value() ==
12835                               max_codec_frames_per_sdu) {
12836                             // Inject the proper Codec Frames Per SDU as the json
12837                             // configs are conservative and will always give us 1
12838                             for (auto& entry : cfg->confs.sink) {
12839                               entry.codec.params.Add(
12840                                       codec_spec_conf::kLeAudioLtvTypeCodecFrameBlocksPerSdu,
12841                                       (uint8_t)max_codec_frames_per_sdu);
12842                             }
12843                             is_fb2_passed_as_requirement = true;
12844                           }
12845                         }
12846                       }
12847                     }
12848                     return cfg;
12849                   }));
12850 
12851   types::BidirectionalPair<stream_parameters> codec_manager_stream_params;
12852   ON_CALL(*mock_codec_manager_, UpdateActiveAudioConfig)
12853           .WillByDefault(
12854                   Invoke([&](const types::BidirectionalPair<stream_parameters>& stream_params,
12855                              types::BidirectionalPair<uint16_t> /*delays_ms*/,
12856                              std::function<void(const offload_config& config, uint8_t direction)>
12857                              /*updater*/) { codec_manager_stream_params = stream_params; }));
12858 
12859   const RawAddress test_address0 = GetTestAddress(0);
12860   int group_id = bluetooth::groups::kGroupUnknown;
12861 
12862   SampleDatabaseParameters remote_params{
12863           .conn_id = 1,
12864           .addr = test_address0,
12865           .add_csis = false,
12866           .set_size = 0,
12867           .rank = 0,
12868           .max_supported_codec_frames_per_sdu = 2,
12869   };
12870   SetSampleDatabaseEarbudsValid(remote_params);
12871 
12872   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12873               OnConnectionState(ConnectionState::CONNECTED, test_address0))
12874           .Times(1);
12875   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12876               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
12877           .WillOnce(DoAll(SaveArg<1>(&group_id)));
12878 
12879   ConnectLeAudio(test_address0);
12880   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
12881 
12882   constexpr int gmcs_ccid = 1;
12883   constexpr int gtbs_ccid = 2;
12884 
12885   // Audio sessions are started only when device gets active
12886   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
12887   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
12888   LeAudioClient::Get()->SetCcidInformation(gmcs_ccid, 4 /* Media */);
12889   LeAudioClient::Get()->SetCcidInformation(gtbs_ccid, 2 /* Phone */);
12890   LeAudioClient::Get()->GroupSetActive(group_id);
12891   SyncOnMainLoop();
12892 
12893   types::BidirectionalPair<std::vector<uint8_t>> ccids = {.sink = {gmcs_ccid}, .source = {}};
12894   EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, ccids)).Times(1);
12895 
12896   stay_at_qos_config_in_start_stream = true;
12897 
12898   UpdateLocalSourceMetadata(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC);
12899   LocalAudioSourceResume(false);
12900 
12901   SyncOnMainLoop();
12902   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
12903   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
12904   ASSERT_TRUE(is_fb2_passed_as_requirement);
12905 
12906   // Verify codec fram blocks per SDU has been applied to the device
12907   ASSERT_NE(0lu, streaming_groups.count(group_id));
12908   uint8_t device_configured_codec_frame_blocks_per_sdu = 0;
12909   auto group = streaming_groups.at(group_id);
12910   for (LeAudioDevice* device = group->GetFirstDevice(); device != nullptr;
12911        device = group->GetNextDevice(device)) {
12912     for (auto& ase : device->ases_) {
12913       if (ase.active) {
12914         auto cfg = ase.codec_config.GetAsCoreCodecConfig();
12915         ASSERT_TRUE(cfg.codec_frames_blocks_per_sdu.has_value());
12916         device_configured_codec_frame_blocks_per_sdu = cfg.codec_frames_blocks_per_sdu.value();
12917       }
12918     }
12919   }
12920 
12921   // Verify the configured codec frame blocks per SDU
12922   ASSERT_EQ(device_configured_codec_frame_blocks_per_sdu,
12923             remote_params.max_supported_codec_frames_per_sdu);
12924 
12925   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(0);
12926   do_in_main_thread(base::BindOnce(
12927           [](int group_id,
12928              bluetooth::le_audio::LeAudioGroupStateMachine::Callbacks* state_machine_callbacks) {
12929             state_machine_callbacks->StatusReportCb(group_id, GroupStreamStatus::STREAMING);
12930           },
12931           group_id, base::Unretained(state_machine_callbacks_)));
12932   SyncOnMainLoop();
12933   Mock::VerifyAndClearExpectations(&mock_state_machine_);
12934 
12935   // Verify Data transfer on one audio source cis
12936   constexpr uint8_t cis_count_out = 1;
12937   constexpr uint8_t cis_count_in = 0;
12938   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in,
12939                         data_len * device_configured_codec_frame_blocks_per_sdu);
12940 
12941   ASSERT_NE(codec_mocks.size(), 0ul);
12942 
12943   // Verify that the initially started session was updated with the new params
12944   ASSERT_EQ(codec_manager_stream_params.sink.codec_frames_blocks_per_sdu, max_codec_frames_per_sdu);
12945 }
12946 
12947 }  // namespace bluetooth::le_audio
12948