• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/btif_common.h"
34 #include "btif/include/mock_core_callbacks.h"
35 #include "btif_storage_mock.h"
36 #include "btm_api_mock.h"
37 #include "btm_iso_api.h"
38 #include "common/message_loop_thread.h"
39 #include "fake_osi.h"
40 #include "gatt/database_builder.h"
41 #include "hardware/bt_gatt_types.h"
42 #include "hardware/bt_le_audio.h"
43 #include "hci/controller_interface_mock.h"
44 #include "internal_include/stack_config.h"
45 #include "le_audio/codec_manager.h"
46 #include "le_audio/mock_codec_interface.h"
47 #include "le_audio_health_status.h"
48 #include "le_audio_set_configuration_provider.h"
49 #include "le_audio_types.h"
50 #include "mock_codec_manager.h"
51 #include "mock_csis_client.h"
52 #include "mock_device_groups.h"
53 #include "mock_state_machine.h"
54 #include "osi/include/properties.h"
55 #include "stack/include/btm_status.h"
56 #include "stack/include/main_thread.h"
57 #include "test/common/mock_functions.h"
58 #include "test/mock/mock_main_shim_entry.h"
59 #include "test/mock/mock_stack_btm_iso.h"
60 
61 #define TEST_BT com::android::bluetooth::flags
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 // Disables most likely false-positives from base::SplitString()
108 extern "C" const char* __asan_default_options();
__asan_default_options()109 extern "C" const char* __asan_default_options() { return "detect_container_overflow=0"; }
110 
111 std::atomic<int> num_async_tasks;
112 bluetooth::common::MessageLoopThread message_loop_thread("test message loop");
get_main_thread()113 bluetooth::common::MessageLoopThread* get_main_thread() { return &message_loop_thread; }
114 
do_in_main_thread(base::OnceClosure task)115 bt_status_t do_in_main_thread(base::OnceClosure task) {
116   // Wrap the task with task counter so we could later know if there are
117   // any callbacks scheduled and we should wait before performing some actions
118   if (!message_loop_thread.DoInThread(base::BindOnce(
119               [](base::OnceClosure task, std::atomic<int>& num_async_tasks) {
120                 std::move(task).Run();
121                 num_async_tasks--;
122               },
123               std::move(task), std::ref(num_async_tasks)))) {
124     bluetooth::log::error("failed to post task to task runner!");
125     return BT_STATUS_FAIL;
126   }
127   num_async_tasks++;
128   return BT_STATUS_SUCCESS;
129 }
130 
do_in_main_thread_delayed(base::OnceClosure task,std::chrono::microseconds)131 bt_status_t do_in_main_thread_delayed(base::OnceClosure task, std::chrono::microseconds /*delay*/) {
132   /* For testing purpose it is ok to just skip delay */
133   return do_in_main_thread(std::move(task));
134 }
135 
init_message_loop_thread()136 static void init_message_loop_thread() {
137   num_async_tasks = 0;
138   message_loop_thread.StartUp();
139   if (!message_loop_thread.IsRunning()) {
140     FAIL() << "unable to create message loop thread.";
141   }
142 
143   if (!message_loop_thread.EnableRealTimeScheduling()) {
144     bluetooth::log::error("Unable to set real time scheduling");
145   }
146 }
147 
cleanup_message_loop_thread()148 static void cleanup_message_loop_thread() { message_loop_thread.ShutDown(); }
149 
BTM_Sec_GetAddressWithType(const RawAddress & bd_addr)150 const tBLE_BD_ADDR BTM_Sec_GetAddressWithType(const RawAddress& bd_addr) {
151   return tBLE_BD_ADDR{.type = BLE_ADDR_PUBLIC, .bda = bd_addr};
152 }
153 
invoke_switch_codec_cb(bool)154 void invoke_switch_codec_cb(bool /*is_low_latency_buffer_size*/) {}
invoke_switch_buffer_size_cb(bool)155 void invoke_switch_buffer_size_cb(bool /*is_low_latency_buffer_size*/) {}
156 
157 const std::string kSmpOptions("mock smp options");
get_pts_avrcp_test(void)158 static bool get_pts_avrcp_test(void) { return false; }
get_pts_secure_only_mode(void)159 static bool get_pts_secure_only_mode(void) { return false; }
get_pts_conn_updates_disabled(void)160 static bool get_pts_conn_updates_disabled(void) { return false; }
get_pts_crosskey_sdp_disable(void)161 static bool get_pts_crosskey_sdp_disable(void) { return false; }
get_pts_smp_options(void)162 static const std::string* get_pts_smp_options(void) { return &kSmpOptions; }
get_pts_smp_failure_case(void)163 static int get_pts_smp_failure_case(void) { return 123; }
get_pts_force_eatt_for_notifications(void)164 static bool get_pts_force_eatt_for_notifications(void) { return false; }
get_pts_connect_eatt_unconditionally(void)165 static bool get_pts_connect_eatt_unconditionally(void) { return false; }
get_pts_connect_eatt_before_encryption(void)166 static bool get_pts_connect_eatt_before_encryption(void) { return false; }
get_pts_unencrypt_broadcast(void)167 static bool get_pts_unencrypt_broadcast(void) { return false; }
get_pts_eatt_peripheral_collision_support(void)168 static bool get_pts_eatt_peripheral_collision_support(void) { return false; }
get_pts_force_le_audio_multiple_contexts_metadata(void)169 static bool get_pts_force_le_audio_multiple_contexts_metadata(void) { return false; }
get_pts_le_audio_disable_ases_before_stopping(void)170 static bool get_pts_le_audio_disable_ases_before_stopping(void) { return false; }
get_all(void)171 static config_t* get_all(void) { return nullptr; }
172 
173 stack_config_t mock_stack_config{
174         .get_pts_avrcp_test = get_pts_avrcp_test,
175         .get_pts_secure_only_mode = get_pts_secure_only_mode,
176         .get_pts_conn_updates_disabled = get_pts_conn_updates_disabled,
177         .get_pts_crosskey_sdp_disable = get_pts_crosskey_sdp_disable,
178         .get_pts_smp_options = get_pts_smp_options,
179         .get_pts_smp_failure_case = get_pts_smp_failure_case,
180         .get_pts_force_eatt_for_notifications = get_pts_force_eatt_for_notifications,
181         .get_pts_connect_eatt_unconditionally = get_pts_connect_eatt_unconditionally,
182         .get_pts_connect_eatt_before_encryption = get_pts_connect_eatt_before_encryption,
183         .get_pts_unencrypt_broadcast = get_pts_unencrypt_broadcast,
184         .get_pts_eatt_peripheral_collision_support = get_pts_eatt_peripheral_collision_support,
185         .get_pts_force_le_audio_multiple_contexts_metadata =
186                 get_pts_force_le_audio_multiple_contexts_metadata,
187         .get_pts_le_audio_disable_ases_before_stopping =
188                 get_pts_le_audio_disable_ases_before_stopping,
189         .get_all = get_all,
190 };
stack_config_get_interface(void)191 const stack_config_t* stack_config_get_interface(void) { return &mock_stack_config; }
192 
IsLeAudioBroadcasterRunning()193 bool LeAudioBroadcaster::IsLeAudioBroadcasterRunning() { return false; }
194 
195 namespace bluetooth::le_audio {
196 class MockLeAudioSourceHalClient;
197 MockLeAudioSourceHalClient* mock_le_audio_source_hal_client_;
198 std::unique_ptr<LeAudioSourceAudioHalClient> owned_mock_le_audio_source_hal_client_;
199 bool is_audio_unicast_source_acquired;
200 
AcquireUnicast()201 std::unique_ptr<LeAudioSourceAudioHalClient> LeAudioSourceAudioHalClient::AcquireUnicast() {
202   if (is_audio_unicast_source_acquired) {
203     return nullptr;
204   }
205   is_audio_unicast_source_acquired = true;
206   return std::move(owned_mock_le_audio_source_hal_client_);
207 }
208 
DebugDump(int)209 void LeAudioSourceAudioHalClient::DebugDump(int /*fd*/) {}
210 
211 class MockLeAudioSinkHalClient;
212 MockLeAudioSinkHalClient* mock_le_audio_sink_hal_client_;
213 std::unique_ptr<LeAudioSinkAudioHalClient> owned_mock_le_audio_sink_hal_client_;
214 bool is_audio_unicast_sink_acquired;
215 
AcquireUnicast()216 std::unique_ptr<LeAudioSinkAudioHalClient> LeAudioSinkAudioHalClient::AcquireUnicast() {
217   if (is_audio_unicast_sink_acquired) {
218     return nullptr;
219   }
220   is_audio_unicast_sink_acquired = true;
221   return std::move(owned_mock_le_audio_sink_hal_client_);
222 }
223 
DebugDump(int)224 void LeAudioSinkAudioHalClient::DebugDump(int /*fd*/) {}
225 
GetTestAddress(uint8_t index)226 static RawAddress GetTestAddress(uint8_t index) {
227   EXPECT_LT(index, UINT8_MAX);
228   RawAddress result = {{0xC0, 0xDE, 0xC0, 0xDE, 0x00, index}};
229   return result;
230 }
231 
232 class MockAudioHalClientCallbacks : public bluetooth::le_audio::LeAudioClientCallbacks {
233 public:
234   MOCK_METHOD((void), OnInitialized, (), (override));
235   MOCK_METHOD((void), OnConnectionState, (ConnectionState state, const RawAddress& address),
236               (override));
237   MOCK_METHOD((void), OnGroupStatus, (int group_id, GroupStatus group_status), (override));
238   MOCK_METHOD((void), OnGroupStreamStatus, (int group_id, GroupStreamStatus group_stream_status),
239               (override));
240   MOCK_METHOD((void), OnGroupNodeStatus,
241               (const RawAddress& bd_addr, int group_id, GroupNodeStatus node_status), (override));
242   MOCK_METHOD((void), OnAudioConf,
243               (uint8_t direction, int group_id, std::optional<std::bitset<32>> snk_audio_location,
244                std::optional<std::bitset<32>> src_audio_location, uint16_t avail_cont),
245               (override));
246   MOCK_METHOD(void, OnSinkAudioLocationAvailable,
247               (const RawAddress& bd_addr, std::optional<std::bitset<32>> snk_audio_location),
248               (override));
249   MOCK_METHOD((void), OnAudioLocalCodecCapabilities,
250               (std::vector<btle_audio_codec_config_t> local_input_capa_codec_conf,
251                std::vector<btle_audio_codec_config_t> local_output_capa_codec_conf),
252               (override));
253   MOCK_METHOD((void), OnAudioGroupCurrentCodecConf,
254               (int group_id, btle_audio_codec_config_t input_codec_conf,
255                btle_audio_codec_config_t output_codec_conf),
256               (override));
257   MOCK_METHOD((void), OnAudioGroupSelectableCodecConf,
258               (int group_id, std::vector<btle_audio_codec_config_t> input_selectable_codec_conf,
259                std::vector<btle_audio_codec_config_t> output_selectable_codec_conf),
260               (override));
261   MOCK_METHOD((void), OnHealthBasedRecommendationAction,
262               (const RawAddress& address, LeAudioHealthBasedAction action), (override));
263   MOCK_METHOD((void), OnHealthBasedGroupRecommendationAction,
264               (int group_id, LeAudioHealthBasedAction action), (override));
265   MOCK_METHOD((void), OnUnicastMonitorModeStatus,
266               (uint8_t direction, UnicastMonitorModeStatus status));
267 };
268 
269 class MockLeAudioSinkHalClient : public LeAudioSinkAudioHalClient {
270 public:
271   MockLeAudioSinkHalClient() = default;
272   MOCK_METHOD((bool), Start,
273               (const LeAudioCodecConfiguration& codecConfiguration,
274                LeAudioSinkAudioHalClient::Callbacks* audioReceiver, DsaModes dsa_modes),
275               (override));
276   MOCK_METHOD((void), Stop, (), (override));
277   MOCK_METHOD((size_t), SendData, (uint8_t* data, uint16_t size), (override));
278   MOCK_METHOD((void), ConfirmStreamingRequest, (), (override));
279   MOCK_METHOD((void), CancelStreamingRequest, (), (override));
280   MOCK_METHOD((void), UpdateRemoteDelay, (uint16_t delay), (override));
281   MOCK_METHOD((void), UpdateAudioConfigToHal, (const ::bluetooth::le_audio::stream_config&),
282               (override));
283   MOCK_METHOD((void), SuspendedForReconfiguration, (), (override));
284   MOCK_METHOD((void), ReconfigurationComplete, (), (override));
285 
286   MOCK_METHOD((void), OnDestroyed, ());
~MockLeAudioSinkHalClient()287   virtual ~MockLeAudioSinkHalClient() override { OnDestroyed(); }
288 };
289 
290 class MockLeAudioSourceHalClient : public LeAudioSourceAudioHalClient {
291 public:
292   MockLeAudioSourceHalClient() = default;
293   MOCK_METHOD((bool), Start,
294               (const LeAudioCodecConfiguration& codecConfiguration,
295                LeAudioSourceAudioHalClient::Callbacks* audioReceiver, DsaModes dsa_modes),
296               (override));
297   MOCK_METHOD((void), Stop, (), (override));
298   MOCK_METHOD((void), ConfirmStreamingRequest, (), (override));
299   MOCK_METHOD((void), CancelStreamingRequest, (), (override));
300   MOCK_METHOD((void), UpdateRemoteDelay, (uint16_t delay), (override));
301   MOCK_METHOD((void), UpdateAudioConfigToHal, (const ::bluetooth::le_audio::stream_config&),
302               (override));
303   MOCK_METHOD((std::optional<broadcaster::BroadcastConfiguration>), GetBroadcastConfig,
304               ((const std::vector<std::pair<types::LeAudioContextType, uint8_t>>&),
305                (const std::optional<std::vector<::bluetooth::le_audio::types::acs_ac_record>>&)),
306               (const override));
307   MOCK_METHOD((std::optional<::bluetooth::le_audio::types::AudioSetConfiguration>),
308               GetUnicastConfig, (const CodecManager::UnicastConfigurationRequirements&),
309               (const override));
310   MOCK_METHOD((void), UpdateBroadcastAudioConfigToHal,
311               (const ::bluetooth::le_audio::broadcast_offload_config&), (override));
312   MOCK_METHOD((void), SuspendedForReconfiguration, (), (override));
313   MOCK_METHOD((void), ReconfigurationComplete, (), (override));
314 
315   MOCK_METHOD((void), OnDestroyed, ());
~MockLeAudioSourceHalClient()316   virtual ~MockLeAudioSourceHalClient() override { OnDestroyed(); }
317 };
318 
319 class UnicastTestNoInit : public Test {
320 public:
321   bool use_handover_mode = false;
322 
323 protected:
RegisterSourceHalClientMock()324   void RegisterSourceHalClientMock() {
325     owned_mock_le_audio_source_hal_client_.reset(new NiceMock<MockLeAudioSourceHalClient>());
326     mock_le_audio_source_hal_client_ =
327             (MockLeAudioSourceHalClient*)owned_mock_le_audio_source_hal_client_.get();
328 
329     is_audio_unicast_source_acquired = false;
330     ON_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _))
331             .WillByDefault([this](const LeAudioCodecConfiguration& /*codec_configuration*/,
332                                   LeAudioSourceAudioHalClient::Callbacks* audioReceiver,
333                                   DsaModes /*dsa_modes*/) {
334               unicast_source_hal_cb_ = audioReceiver;
335               return true;
336             });
337     ON_CALL(*mock_le_audio_source_hal_client_, OnDestroyed).WillByDefault([]() {
338       mock_le_audio_source_hal_client_ = nullptr;
339       is_audio_unicast_source_acquired = false;
340     });
341   }
342 
RegisterSinkHalClientMock()343   void RegisterSinkHalClientMock() {
344     owned_mock_le_audio_sink_hal_client_.reset(new NiceMock<MockLeAudioSinkHalClient>());
345     mock_le_audio_sink_hal_client_ =
346             (MockLeAudioSinkHalClient*)owned_mock_le_audio_sink_hal_client_.get();
347 
348     is_audio_unicast_sink_acquired = false;
349     ON_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _))
350             .WillByDefault([this](const LeAudioCodecConfiguration& /*codec_configuration*/,
351                                   LeAudioSinkAudioHalClient::Callbacks* audioReceiver,
352                                   DsaModes /*dsa_modes*/) {
353               unicast_sink_hal_cb_ = audioReceiver;
354               return true;
355             });
356     ON_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed).WillByDefault([]() {
357       mock_le_audio_sink_hal_client_ = nullptr;
358       is_audio_unicast_sink_acquired = false;
359     });
360   }
361 
SetUpMockAudioHal()362   void SetUpMockAudioHal() {
363     /* Since these are returned by the Acquire() methods as unique_ptrs, we
364      * will not free them manually.
365      */
366     RegisterSourceHalClientMock();
367 
368     owned_mock_le_audio_sink_hal_client_.reset(new NiceMock<MockLeAudioSinkHalClient>());
369     mock_le_audio_sink_hal_client_ =
370             (MockLeAudioSinkHalClient*)owned_mock_le_audio_sink_hal_client_.get();
371 
372     owned_mock_le_audio_source_hal_client_.reset(new NiceMock<MockLeAudioSourceHalClient>());
373     mock_le_audio_source_hal_client_ =
374             (MockLeAudioSourceHalClient*)owned_mock_le_audio_source_hal_client_.get();
375 
376     is_audio_unicast_source_acquired = false;
377     ON_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _))
378             .WillByDefault([this](const LeAudioCodecConfiguration& /*codec_configuration*/,
379                                   LeAudioSourceAudioHalClient::Callbacks* audioReceiver,
380                                   DsaModes /*dsa_modes*/) {
381               unicast_source_hal_cb_ = audioReceiver;
382               return true;
383             });
384     ON_CALL(*mock_le_audio_source_hal_client_, OnDestroyed).WillByDefault([]() {
385       mock_le_audio_source_hal_client_ = nullptr;
386       is_audio_unicast_source_acquired = false;
387     });
388 
389     is_audio_unicast_sink_acquired = false;
390     ON_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _))
391             .WillByDefault([this](const LeAudioCodecConfiguration& /*codec_configuration*/,
392                                   LeAudioSinkAudioHalClient::Callbacks* audioReceiver,
393                                   DsaModes /*dsa_modes*/) {
394               unicast_sink_hal_cb_ = audioReceiver;
395               return true;
396             });
397     ON_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed).WillByDefault([]() {
398       mock_le_audio_sink_hal_client_ = nullptr;
399       is_audio_unicast_sink_acquired = false;
400     });
401 
402     ON_CALL(*mock_le_audio_sink_hal_client_, SendData)
403             .WillByDefault([](uint8_t* /*data*/, uint16_t size) { return size; });
404 
405     // HAL
406     ON_CALL(mock_hal_2_1_verifier, Call()).WillByDefault([]() -> bool { return true; });
407   }
408 
InjectGroupDeviceRemoved(const RawAddress & address,int group_id)409   void InjectGroupDeviceRemoved(const RawAddress& address, int group_id) {
410     group_callbacks_->OnGroupMemberRemoved(address, group_id);
411   }
412 
InjectGroupDeviceAdded(const RawAddress & address,int group_id)413   void InjectGroupDeviceAdded(const RawAddress& address, int group_id) {
414     bluetooth::Uuid uuid = bluetooth::le_audio::uuid::kCapServiceUuid;
415 
416     int group_members_num = 0;
417     for (const auto& [addr, id] : groups) {
418       if (id == group_id) {
419         group_members_num++;
420       }
421     }
422 
423     bool first_device = (group_members_num == 1);
424     do_in_main_thread(base::BindOnce(
425             [](const RawAddress& addr, int group_id, bluetooth::Uuid uuid,
426                bluetooth::groups::DeviceGroupsCallbacks* group_callbacks, bool first_device) {
427               if (first_device) {
428                 group_callbacks->OnGroupAdded(addr, uuid, group_id);
429               } else {
430                 group_callbacks->OnGroupMemberAdded(addr, group_id);
431               }
432             },
433             address, group_id, uuid, base::Unretained(this->group_callbacks_), first_device));
434   }
435 
InjectServiceChangedEvent(const RawAddress & address,uint16_t conn_id)436   void InjectServiceChangedEvent(const RawAddress& address, uint16_t conn_id) {
437     tBTA_GATTC_SERVICE_CHANGED event_data = {.remote_bda = address, .conn_id = conn_id};
438 
439     do_in_main_thread(base::BindOnce(
440             [](tBTA_GATTC_CBACK* gatt_callback, tBTA_GATTC_SERVICE_CHANGED event_data) {
441               gatt_callback(BTA_GATTC_SRVC_CHG_EVT, (tBTA_GATTC*)&event_data);
442             },
443             base::Unretained(this->gatt_callback), event_data));
444   }
445 
InjectConnectedEvent(const RawAddress & address,uint16_t conn_id,tGATT_STATUS status=GATT_SUCCESS)446   void InjectConnectedEvent(const RawAddress& address, uint16_t conn_id,
447                             tGATT_STATUS status = GATT_SUCCESS) {
448     ASSERT_NE(conn_id, GATT_INVALID_CONN_ID);
449     tBTA_GATTC_OPEN event_data = {
450             .status = status,
451             .conn_id = conn_id,
452             .client_if = gatt_if,
453             .remote_bda = address,
454             .transport = BT_TRANSPORT_LE,
455             .mtu = 240,
456     };
457 
458     if (status == GATT_SUCCESS) {
459       ASSERT_NE(peer_devices.count(conn_id), 0u);
460       peer_devices.at(conn_id)->connected = true;
461     }
462 
463     do_in_main_thread(base::BindOnce(
464             [](tBTA_GATTC_CBACK* gatt_callback, tBTA_GATTC_OPEN event_data) {
465               gatt_callback(BTA_GATTC_OPEN_EVT, (tBTA_GATTC*)&event_data);
466             },
467             base::Unretained(this->gatt_callback), event_data));
468   }
469 
InjectEncryptionChangedEvent(const RawAddress & address)470   void InjectEncryptionChangedEvent(const RawAddress& address) {
471     tBTA_GATTC_ENC_CMPL_CB event_data = {
472             .client_if = gatt_if,
473             .remote_bda = address,
474     };
475 
476     do_in_main_thread(base::BindOnce(
477             [](tBTA_GATTC_CBACK* gatt_callback, tBTA_GATTC_ENC_CMPL_CB event_data) {
478               gatt_callback(BTA_GATTC_ENC_CMPL_CB_EVT, (tBTA_GATTC*)&event_data);
479             },
480             base::Unretained(this->gatt_callback), event_data));
481   }
482 
TriggerDisconnectionFromApp(const RawAddress & address)483   void TriggerDisconnectionFromApp(const RawAddress& address) {
484     do_in_main_thread(base::BindOnce(
485             [](LeAudioClient* client, const RawAddress& address) { client->Disconnect(address); },
486             LeAudioClient::Get(), address));
487   }
488 
InjectDisconnectedEvent(uint16_t conn_id,tGATT_DISCONN_REASON reason=GATT_CONN_TERMINATE_LOCAL_HOST)489   void InjectDisconnectedEvent(uint16_t conn_id,
490                                tGATT_DISCONN_REASON reason = GATT_CONN_TERMINATE_LOCAL_HOST) {
491     ASSERT_NE(conn_id, GATT_INVALID_CONN_ID);
492     ASSERT_NE(peer_devices.count(conn_id), 0u);
493 
494     tBTA_GATTC_CLOSE event_data = {
495             .conn_id = conn_id,
496             .status = GATT_SUCCESS,
497             .client_if = gatt_if,
498             .remote_bda = peer_devices.at(conn_id)->addr,
499             .reason = reason,
500     };
501 
502     peer_devices.at(conn_id)->connected = false;
503     do_in_main_thread(base::BindOnce(
504             [](tBTA_GATTC_CBACK* gatt_callback, tBTA_GATTC_CLOSE event_data) {
505               gatt_callback(BTA_GATTC_CLOSE_EVT, (tBTA_GATTC*)&event_data);
506             },
507             base::Unretained(this->gatt_callback), event_data));
508   }
509 
InjectPhyChangedEvent(uint16_t conn_id,uint8_t tx_phy,uint8_t rx_phy,tGATT_STATUS status)510   void InjectPhyChangedEvent(uint16_t conn_id, uint8_t tx_phy, uint8_t rx_phy,
511                              tGATT_STATUS status) {
512     ASSERT_NE(conn_id, GATT_INVALID_CONN_ID);
513     tBTA_GATTC_PHY_UPDATE event_data = {
514             .conn_id = conn_id,
515             .tx_phy = tx_phy,
516             .rx_phy = rx_phy,
517             .status = status,
518     };
519 
520     do_in_main_thread(base::BindOnce(
521             [](tBTA_GATTC_CBACK* gatt_callback, tBTA_GATTC_PHY_UPDATE event_data) {
522               gatt_callback(BTA_GATTC_PHY_UPDATE_EVT, (tBTA_GATTC*)&event_data);
523             },
524             base::Unretained(this->gatt_callback), event_data));
525   }
526 
InjectSearchCompleteEvent(uint16_t conn_id)527   void InjectSearchCompleteEvent(uint16_t conn_id) {
528     ASSERT_NE(conn_id, GATT_INVALID_CONN_ID);
529     tBTA_GATTC_SEARCH_CMPL event_data = {
530             .conn_id = conn_id,
531             .status = GATT_SUCCESS,
532     };
533 
534     do_in_main_thread(base::BindOnce(
535             [](tBTA_GATTC_CBACK* gatt_callback, tBTA_GATTC_SEARCH_CMPL event_data) {
536               gatt_callback(BTA_GATTC_SEARCH_CMPL_EVT, (tBTA_GATTC*)&event_data);
537             },
538             base::Unretained(this->gatt_callback), event_data));
539   }
540 
InjectNotificationEvent(const RawAddress & test_address,uint16_t conn_id,uint16_t handle,std::vector<uint8_t> value)541   void InjectNotificationEvent(const RawAddress& test_address, uint16_t conn_id, uint16_t handle,
542                                std::vector<uint8_t> value) {
543     ASSERT_NE(conn_id, GATT_INVALID_CONN_ID);
544     tBTA_GATTC_NOTIFY event_data = {
545             .conn_id = conn_id,
546             .bda = test_address,
547             .handle = handle,
548             .len = (uint8_t)value.size(),
549             .is_notify = true,
550     };
551 
552     std::copy(value.begin(), value.end(), event_data.value);
553     do_in_main_thread(base::BindOnce(
554             [](tBTA_GATTC_CBACK* gatt_callback, tBTA_GATTC_NOTIFY event_data) {
555               gatt_callback(BTA_GATTC_NOTIF_EVT, (tBTA_GATTC*)&event_data);
556             },
557             base::Unretained(this->gatt_callback), event_data));
558   }
559 
InjectContextTypes(const RawAddress & test_address,uint16_t conn_id,uint16_t handle,AudioContexts sink_ctxs,AudioContexts source_ctxs)560   void InjectContextTypes(const RawAddress& test_address, uint16_t conn_id, uint16_t handle,
561                           AudioContexts sink_ctxs, AudioContexts source_ctxs) {
562     std::vector<uint8_t> contexts = {
563             (uint8_t)(sink_ctxs.value()), (uint8_t)(sink_ctxs.value() >> 8),
564             (uint8_t)(source_ctxs.value()), (uint8_t)(source_ctxs.value() >> 8)};
565 
566     InjectNotificationEvent(test_address, conn_id, handle, contexts);
567   }
568 
InjectSupportedContextTypes(const RawAddress & test_address,uint16_t conn_id,AudioContexts sink_ctxs,AudioContexts source_ctxs)569   void InjectSupportedContextTypes(const RawAddress& test_address, uint16_t conn_id,
570                                    AudioContexts sink_ctxs, AudioContexts source_ctxs) {
571     /* 0x0077 pacs->supp_contexts_char + 1 */
572     InjectContextTypes(test_address, conn_id, 0x0077, sink_ctxs, source_ctxs);
573     SyncOnMainLoop();
574   }
575 
InjectAvailableContextTypes(const RawAddress & test_address,uint16_t conn_id,AudioContexts sink_ctxs,AudioContexts source_ctxs,bool sync_on_mainloop=true)576   void InjectAvailableContextTypes(const RawAddress& test_address, uint16_t conn_id,
577                                    AudioContexts sink_ctxs, AudioContexts source_ctxs,
578                                    bool sync_on_mainloop = true) {
579     /* 0x0074 is pacs->avail_contexts_char + 1 */
580     InjectContextTypes(test_address, conn_id, 0x0074, sink_ctxs, source_ctxs);
581     if (sync_on_mainloop) {
582       SyncOnMainLoop();
583     }
584   }
585 
SetUpMockGatt()586   void SetUpMockGatt() {
587     // default action for GetCharacteristic function call
588     ON_CALL(mock_gatt_interface_, GetCharacteristic(_, _))
589             .WillByDefault(
590                     Invoke([&](uint16_t conn_id, uint16_t handle) -> const gatt::Characteristic* {
591                       std::list<gatt::Service>& services = peer_devices.at(conn_id)->services;
592                       for (auto const& service : services) {
593                         for (auto const& characteristic : service.characteristics) {
594                           if (characteristic.value_handle == handle) {
595                             return &characteristic;
596                           }
597                         }
598                       }
599 
600                       return nullptr;
601                     }));
602 
603     // default action for GetOwningService function call
604     ON_CALL(mock_gatt_interface_, GetOwningService(_, _))
605             .WillByDefault(Invoke([&](uint16_t conn_id, uint16_t handle) -> const gatt::Service* {
606               std::list<gatt::Service>& services = peer_devices.at(conn_id)->services;
607               for (auto const& service : services) {
608                 if (service.handle <= handle && service.end_handle >= handle) {
609                   return &service;
610                 }
611               }
612 
613               return nullptr;
614             }));
615 
616     // default action for ServiceSearchRequest function call
617     ON_CALL(mock_gatt_interface_, ServiceSearchRequest(_, _))
618             .WillByDefault(WithArg<0>(
619                     Invoke([&](uint16_t conn_id) { InjectSearchCompleteEvent(conn_id); })));
620 
621     // default action for GetServices function call
622     ON_CALL(mock_gatt_interface_, GetServices(_))
623             .WillByDefault(WithArg<0>(Invoke([&](uint16_t conn_id) -> std::list<gatt::Service>* {
624               return &peer_devices.at(conn_id)->services;
625             })));
626 
627     // default action for RegisterForNotifications function call
628     ON_CALL(mock_gatt_interface_, RegisterForNotifications(gatt_if, _, _))
629             .WillByDefault(Return(GATT_SUCCESS));
630 
631     // default action for DeregisterForNotifications function call
632     ON_CALL(mock_gatt_interface_, DeregisterForNotifications(gatt_if, _, _))
633             .WillByDefault(Return(GATT_SUCCESS));
634 
635     // default action for WriteDescriptor function call
636     ON_CALL(mock_gatt_queue_, WriteDescriptor(_, _, _, _, _, _))
637             .WillByDefault(Invoke([this](uint16_t conn_id, uint16_t handle,
638                                          std::vector<uint8_t> value,
639                                          tGATT_WRITE_TYPE /*write_type*/, GATT_WRITE_OP_CB cb,
640                                          void* cb_data) -> void {
641               auto& ascs = peer_devices.at(conn_id)->ascs;
642               uint8_t idx;
643 
644               if (handle == ascs->ctp_ccc) {
645                 value = UINT16_TO_VEC_UINT8(ascs->ctp_ccc_val);
646               } else {
647                 for (idx = 0; idx < max_num_of_ases; idx++) {
648                   if (handle == ascs->sink_ase_ccc[idx] + 1) {
649                     value = UINT16_TO_VEC_UINT8(ascs->sink_ase_ccc_val[idx]);
650                     break;
651                   }
652                   if (handle == ascs->source_ase_char[idx] + 1) {
653                     value = UINT16_TO_VEC_UINT8(ascs->source_ase_ccc_val[idx]);
654                     break;
655                   }
656                 }
657               }
658 
659               if (cb) {
660                 do_in_main_thread(base::BindOnce(
661                         [](GATT_WRITE_OP_CB cb, uint16_t conn_id, uint16_t handle, uint16_t len,
662                            uint8_t* value, void* cb_data) {
663                           cb(conn_id, GATT_SUCCESS, handle, len, value, cb_data);
664                         },
665                         cb, conn_id, handle, value.size(), value.data(), cb_data));
666               }
667             }));
668 
669     global_conn_id = 1;
670     ON_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_DIRECT_CONNECTION, _))
671             .WillByDefault(Invoke([&](tGATT_IF /*client_if*/, const RawAddress& remote_bda,
672                                       bool /*is_direct*/, bool /*opportunistic*/) {
673               InjectConnectedEvent(remote_bda, global_conn_id++);
674             }));
675 
676     ON_CALL(mock_gatt_interface_, Close(_)).WillByDefault(Invoke([&](uint16_t conn_id) {
677       ASSERT_NE(conn_id, GATT_INVALID_CONN_ID);
678       InjectDisconnectedEvent(conn_id);
679     }));
680 
681     // default Characteristic read handler dispatches requests to service mocks
682     ON_CALL(mock_gatt_queue_, ReadCharacteristic(_, _, _, _))
683             .WillByDefault(Invoke([&](uint16_t conn_id, uint16_t handle, GATT_READ_OP_CB cb,
684                                       void* cb_data) {
685               do_in_main_thread(base::BindOnce(
686                       [](std::map<uint16_t, std::unique_ptr<NiceMock<MockDeviceWrapper>>>*
687                                  peer_devices,
688                          uint16_t conn_id, uint16_t handle, GATT_READ_OP_CB cb,
689                          void* cb_data) -> void {
690                         if (peer_devices->count(conn_id)) {
691                           auto& device = peer_devices->at(conn_id);
692                           auto svc = std::find_if(device->services.begin(), device->services.end(),
693                                                   [handle](const gatt::Service& svc) {
694                                                     return (handle >= svc.handle) &&
695                                                            (handle <= svc.end_handle);
696                                                   });
697                           if (svc == device->services.end()) {
698                             return;
699                           }
700 
701                           GattStatus status;
702                           std::vector<uint8_t> value;
703                           // Dispatch to mockable handler functions
704                           if (svc->handle == device->csis->start) {
705                             std::tie(status, value) =
706                                     device->csis->OnGetCharacteristicValue(handle);
707                           } else if (svc->handle == device->cas->start) {
708                             std::tie(status, value) = device->cas->OnGetCharacteristicValue(handle);
709                           } else if (svc->handle == device->ascs->start) {
710                             std::tie(status, value) =
711                                     device->ascs->OnGetCharacteristicValue(handle);
712                           } else if (svc->handle == device->pacs->start) {
713                             std::tie(status, value) =
714                                     device->pacs->OnGetCharacteristicValue(handle);
715                           } else {
716                             return;
717                           }
718 
719                           cb(conn_id, status, handle, value.size(), value.data(), cb_data);
720                         }
721                       },
722                       &peer_devices, conn_id, handle, cb, cb_data));
723             }));
724 
725     // default multiple Characteristic read handler dispatches requests to service mocks
726     ON_CALL(mock_gatt_queue_, ReadMultiCharacteristic(_, _, _, _))
727             .WillByDefault(Invoke([&](uint16_t conn_id, tBTA_GATTC_MULTI& handles,
728                                       GATT_READ_MULTI_OP_CB cb, void* cb_data) {
729               do_in_main_thread(base::BindOnce(
730                       [](std::map<uint16_t, std::unique_ptr<NiceMock<MockDeviceWrapper>>>*
731                                  peer_devices,
732                          uint16_t conn_id, tBTA_GATTC_MULTI handles, GATT_READ_MULTI_OP_CB cb,
733                          void* cb_data) -> void {
734                         if (!peer_devices->count(conn_id)) {
735                           return;
736                         }
737                         auto& device = peer_devices->at(conn_id);
738 
739                         auto get_char_value_helper = [&](NiceMock<MockDeviceWrapper>& device,
740                                                          uint16_t handle) {
741                           auto svc = std::find_if(device.services.begin(), device.services.end(),
742                                                   [handle](const gatt::Service& svc) {
743                                                     return (handle >= svc.handle) &&
744                                                            (handle <= svc.end_handle);
745                                                   });
746                           if (svc == device.services.end()) {
747                             return std::make_pair(GATT_ERROR, std::vector<uint8_t>());
748                           }
749 
750                           // Dispatch to mockable handler functions
751                           if (svc->handle == device.csis->start) {
752                             return device.csis->OnGetCharacteristicValue(handle);
753                           } else if (svc->handle == device.cas->start) {
754                             return device.cas->OnGetCharacteristicValue(handle);
755                           } else if (svc->handle == device.ascs->start) {
756                             return device.ascs->OnGetCharacteristicValue(handle);
757                           } else if (svc->handle == device.pacs->start) {
758                             return device.pacs->OnGetCharacteristicValue(handle);
759                           } else {
760                             return std::make_pair(GATT_ERROR, std::vector<uint8_t>());
761                           };
762                         };
763                         std::array<uint8_t, GATT_MAX_ATTR_LEN> value;
764                         uint16_t value_end = 0;
765                         for (int i = 0; i < handles.num_attr; i++) {
766                           GattStatus status;
767                           std::vector<uint8_t> curr_val;
768                           std::tie(status, curr_val) =
769                                   get_char_value_helper(*device, handles.handles[i]);
770 
771                           if (status != GATT_SUCCESS) {
772                             cb(conn_id, status, handles, 0, value.data(), cb_data);
773                             return;
774                           }
775 
776                           value[value_end] = (curr_val.size() & 0x00ff);
777                           value[value_end + 1] = (curr_val.size() & 0xff00) >> 8;
778                           value_end += 2;
779 
780                           // concatenate all read values together
781                           std::copy(curr_val.begin(), curr_val.end(), value.data() + value_end);
782                           value_end += curr_val.size();
783                         }
784                         cb(conn_id, GATT_SUCCESS, handles, value_end, value.data(), cb_data);
785                       },
786                       &peer_devices, conn_id, handles, cb, cb_data));
787             }));
788   }
789 
SetUpMockGroups()790   void SetUpMockGroups() {
791     MockCsisClient::SetMockInstanceForTesting(&mock_csis_client_module_);
792     MockDeviceGroups::SetMockInstanceForTesting(&mock_groups_module_);
793     MockLeAudioGroupStateMachine::SetMockInstanceForTesting(&mock_state_machine_);
794 
795     ON_CALL(mock_csis_client_module_, Get()).WillByDefault(Return(&mock_csis_client_module_));
796 
797     // Store group callbacks so that we could inject grouping events
798     group_callbacks_ = nullptr;
799     ON_CALL(mock_groups_module_, Initialize(_)).WillByDefault(SaveArg<0>(&group_callbacks_));
800 
801     ON_CALL(mock_groups_module_, GetGroupId(_, _))
802             .WillByDefault([this](const RawAddress& addr, bluetooth::Uuid /*uuid*/) {
803               if (groups.find(addr) != groups.end()) {
804                 return groups.at(addr);
805               }
806               return bluetooth::groups::kGroupUnknown;
807             });
808 
809     ON_CALL(mock_groups_module_, RemoveDevice(_, _))
810             .WillByDefault([this](const RawAddress& addr, int /*group_id*/) {
811               int group_id = -1;
812               if (groups.find(addr) != groups.end()) {
813                 group_id = groups[addr];
814                 groups.erase(addr);
815               }
816               if (group_id < 0) {
817                 return;
818               }
819 
820               do_in_main_thread(base::BindOnce(
821                       [](const RawAddress& address, int group_id,
822                          bluetooth::groups::DeviceGroupsCallbacks* group_callbacks) {
823                         group_callbacks->OnGroupMemberRemoved(address, group_id);
824                       },
825                       addr, group_id, base::Unretained(group_callbacks_)));
826             });
827 
828     // Our test devices have unique LSB - use it for unique grouping when
829     // devices added with a non-CIS context and no grouping info
830     ON_CALL(mock_groups_module_, AddDevice(_, bluetooth::le_audio::uuid::kCapServiceUuid, _))
831             .WillByDefault(
832                     [this](const RawAddress& addr,
833                            bluetooth::Uuid /*uuid*/ = bluetooth::le_audio::uuid::kCapServiceUuid,
834                            int group_id = bluetooth::groups::kGroupUnknown) -> int {
835                       if (group_id == bluetooth::groups::kGroupUnknown) {
836                         /* Generate group id from address */
837                         groups[addr] = addr.address[RawAddress::kLength - 1];
838                         group_id = groups[addr];
839                       } else {
840                         groups[addr] = group_id;
841                       }
842 
843                       InjectGroupDeviceAdded(addr, groups[addr]);
844                       return addr.address[RawAddress::kLength - 1];
845                     });
846 
847     ON_CALL(mock_state_machine_, Initialize(_))
848             .WillByDefault(SaveArg<0>(&state_machine_callbacks_));
849 
850     ON_CALL(mock_state_machine_, ConfigureStream(_, _, _, _, _))
851             .WillByDefault([this](LeAudioDeviceGroup* group, types::LeAudioContextType context_type,
852                                   types::BidirectionalPair<types::AudioContexts>
853                                           metadata_context_types,
854                                   types::BidirectionalPair<std::vector<uint8_t>> ccid_lists,
855                                   bool configure_qos) {
856               auto group_state = group->GetState();
857               bool isReconfiguration = group->IsPendingConfiguration();
858 
859               log::info(
860                       "ConfigureStream: group {} state {}, context type {} sink metadata_ctx {}, "
861                       "source metadata_ctx {}, ccid_sink size {}, ccid_source_size {}, "
862                       "isReconfiguration {}",
863                       group->group_id_, bluetooth::common::ToString(group_state),
864                       bluetooth::common::ToString(context_type),
865                       bluetooth::common::ToString(metadata_context_types.sink),
866                       bluetooth::common::ToString(metadata_context_types.source),
867                       ccid_lists.sink.size(), ccid_lists.source.size(), isReconfiguration);
868 
869               /* Do what ReleaseCisIds(group) does: start */
870               LeAudioDevice* leAudioDevice = group->GetFirstDevice();
871               while (leAudioDevice != nullptr) {
872                 for (auto& ase : leAudioDevice->ases_) {
873                   ase.cis_id = bluetooth::le_audio::kInvalidCisId;
874                 }
875                 leAudioDevice = group->GetNextDevice(leAudioDevice);
876               }
877               group->ClearAllCises();
878               /* end */
879 
880               if (!group->Configure(context_type, metadata_context_types, ccid_lists)) {
881                 log::error("ConfigureStream: Could not configure ASEs for group {} content type {}",
882                            group->group_id_, int(context_type));
883 
884                 return false;
885               }
886 
887               group->cig.GenerateCisIds(context_type);
888 
889               types::AseState config_state =
890                       types::AseState::BTA_LE_AUDIO_ASE_STATE_CODEC_CONFIGURED;
891 
892               if (configure_qos) {
893                 // Make sure CIG is created
894                 config_state = types::AseState::BTA_LE_AUDIO_ASE_STATE_QOS_CONFIGURED;
895                 group->cig.SetState(types::CigState::CREATED);
896               }
897 
898               for (LeAudioDevice* device = group->GetFirstDevice(); device != nullptr;
899                    device = group->GetNextDevice(device)) {
900                 if (!group->cig.AssignCisIds(device)) {
901                   continue;
902                 }
903 
904                 if (group->cig.GetState() == types::CigState::CREATED) {
905                   group->AssignCisConnHandlesToAses(device);
906                 }
907 
908                 for (auto& ase : device->ases_) {
909                   if (!ase.active) {
910                     continue;
911                   }
912 
913                   ase.cis_state = types::CisState::IDLE;
914                   ase.data_path_state = types::DataPathState::IDLE;
915                   ase.state = config_state;
916                 }
917               }
918 
919               // Inject the state
920               group->SetTargetState(config_state);
921               group->SetState(group->GetTargetState());
922               if (group->IsPendingConfiguration()) {
923                 group->ClearPendingConfiguration();
924                 do_in_main_thread(base::BindOnce(
925                         [](int group_id, bluetooth::le_audio::LeAudioGroupStateMachine::Callbacks*
926                                                  state_machine_callbacks) {
927                           state_machine_callbacks->StatusReportCb(
928                                   group_id, GroupStreamStatus::CONFIGURED_BY_USER);
929                         },
930                         group->group_id_, base::Unretained(this->state_machine_callbacks_)));
931               }
932               return true;
933             });
934 
935     ON_CALL(mock_state_machine_, AttachToStream(_, _, _))
936             .WillByDefault([this](LeAudioDeviceGroup* group, LeAudioDevice* leAudioDevice,
937                                   types::BidirectionalPair<std::vector<uint8_t>> ccids) {
938               log::info(
939                       "AttachToStream: group_id {}, address {}, current_state {}, target_state {}",
940                       group->group_id_, leAudioDevice->address_,
941                       bluetooth::common::ToString(group->GetState()),
942                       bluetooth::common::ToString(group->GetTargetState()));
943 
944               if (group->GetState() != types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING) {
945                 if (group->GetTargetState() == types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING) {
946                   attach_to_stream_scheduled = true;
947                 }
948 
949                 return false;
950               }
951 
952               group->Configure(group->GetConfigurationContextType(), group->GetMetadataContexts(),
953                                ccids);
954               if (!group->cig.AssignCisIds(leAudioDevice)) {
955                 return false;
956               }
957               group->AssignCisConnHandlesToAses(leAudioDevice);
958 
959               auto* stream_conf = &group->stream_conf;
960 
961               for (auto& ase : leAudioDevice->ases_) {
962                 if (!ase.active) {
963                   continue;
964                 }
965 
966                 // And also skip the ase establishment procedure which should
967                 // be tested as part of the state machine unit tests
968                 ase.cis_state = types::CisState::CONNECTED;
969                 ase.data_path_state = types::DataPathState::CONFIGURED;
970                 ase.state = types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING;
971 
972                 uint16_t cis_conn_hdl = ase.cis_conn_hdl;
973                 auto core_config = ase.codec_config.params.GetAsCoreCodecConfig();
974 
975                 /* Copied from state_machine.cc ProcessHciNotifSetupIsoDataPath */
976                 if (ase.direction == bluetooth::le_audio::types::kLeAudioDirectionSource) {
977                   auto iter = std::find_if(
978                           stream_conf->stream_params.source.stream_config.stream_map.begin(),
979                           stream_conf->stream_params.source.stream_config.stream_map.end(),
980                           [cis_conn_hdl](auto& info) {
981                             return cis_conn_hdl == info.stream_handle;
982                           });
983 
984                   if (iter == stream_conf->stream_params.source.stream_config.stream_map.end()) {
985                     stream_conf->stream_params.source.stream_config.stream_map.emplace_back(
986                             stream_map_info(ase.cis_conn_hdl, *core_config.audio_channel_allocation,
987                                             true));
988 
989                     stream_conf->stream_params.source.num_of_devices++;
990                     stream_conf->stream_params.source.num_of_channels +=
991                             ase.codec_config.channel_count_per_iso_stream;
992 
993                     log::info(
994                             "AttachToStream: Added Source Stream Configuration. CIS Connection "
995                             "Handle: "
996                             "{}, Audio Channel Allocation: {}, Source Number Of "
997                             "Devices: {}, Source Number Of Channels: {}",
998                             ase.cis_conn_hdl, *core_config.audio_channel_allocation,
999                             stream_conf->stream_params.source.num_of_devices,
1000                             stream_conf->stream_params.source.num_of_channels);
1001                   }
1002                 } else {
1003                   auto iter = std::find_if(
1004                           stream_conf->stream_params.sink.stream_config.stream_map.begin(),
1005                           stream_conf->stream_params.sink.stream_config.stream_map.end(),
1006                           [cis_conn_hdl](auto& info) {
1007                             return cis_conn_hdl == info.stream_handle;
1008                           });
1009 
1010                   if (iter == stream_conf->stream_params.sink.stream_config.stream_map.end()) {
1011                     stream_conf->stream_params.sink.stream_config.stream_map.emplace_back(
1012                             stream_map_info(ase.cis_conn_hdl, *core_config.audio_channel_allocation,
1013                                             true));
1014 
1015                     stream_conf->stream_params.sink.num_of_devices++;
1016                     stream_conf->stream_params.sink.num_of_channels +=
1017                             ase.codec_config.channel_count_per_iso_stream;
1018 
1019                     log::info(
1020                             "AttachToStream: Added Sink Stream Configuration. CIS Connection "
1021                             "Handle: "
1022                             "{}, Audio Channel Allocation: {}, Sink Number Of Devices: "
1023                             "{}, Sink Number Of Channels: {}",
1024                             ase.cis_conn_hdl, *core_config.audio_channel_allocation,
1025                             stream_conf->stream_params.sink.num_of_devices,
1026                             stream_conf->stream_params.sink.num_of_channels);
1027                   }
1028                 }
1029               }
1030 
1031               // When the device attaches to the stream we send again the state machine state to
1032               // stimulate the stream map update
1033               // see LeAudioGroupStateMachineImpl::SendStreamingStatusCbIfNeeded(group);
1034               if (!group->HaveAllCisesDisconnected() &&
1035                   (group->GetState() == types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING) &&
1036                   (group->GetTargetState() == types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING)) {
1037                 do_in_main_thread(base::BindOnce(
1038                         [](int group_id, bluetooth::le_audio::LeAudioGroupStateMachine::Callbacks*
1039                                                  state_machine_callbacks) {
1040                           state_machine_callbacks->StatusReportCb(group_id,
1041                                                                   GroupStreamStatus::STREAMING);
1042                         },
1043                         group->group_id_, base::Unretained(this->state_machine_callbacks_)));
1044               }
1045 
1046               return true;
1047             });
1048 
1049     ON_CALL(mock_state_machine_, StartStream(_, _, _, _))
1050             .WillByDefault([this](LeAudioDeviceGroup* group, types::LeAudioContextType context_type,
1051                                   types::BidirectionalPair<types::AudioContexts>
1052                                           metadata_context_types,
1053                                   types::BidirectionalPair<std::vector<uint8_t>> ccid_lists) {
1054               auto group_state = group->GetState();
1055               log::info(
1056                       "StartStream: group {} state {}, context type {} sink metadata_ctx {}, "
1057                       "source metadata_ctx {}, ccid_sink size {}, ccid_source_size {}",
1058                       group->group_id_, bluetooth::common::ToString(group_state),
1059                       bluetooth::common::ToString(context_type),
1060                       bluetooth::common::ToString(metadata_context_types.sink),
1061                       bluetooth::common::ToString(metadata_context_types.source),
1062                       ccid_lists.sink.size(), ccid_lists.source.size());
1063 
1064               /* Do nothing if already streaming - the implementation would
1065                * probably update the metadata.
1066                */
1067               if (group_state == types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING) {
1068                 return true;
1069               }
1070 
1071               // Inject the state
1072               group->SetTargetState(types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
1073 
1074               if (group_state != types::AseState::BTA_LE_AUDIO_ASE_STATE_QOS_CONFIGURED) {
1075                 /* Do what ReleaseCisIds(group) does: start */
1076                 LeAudioDevice* leAudioDevice = group->GetFirstDevice();
1077                 while (leAudioDevice != nullptr) {
1078                   for (auto& ase : leAudioDevice->ases_) {
1079                     ase.cis_id = bluetooth::le_audio::kInvalidCisId;
1080                   }
1081                   leAudioDevice = group->GetNextDevice(leAudioDevice);
1082                 }
1083                 group->ClearAllCises();
1084                 /* end */
1085 
1086                 if (!group->Configure(context_type, metadata_context_types, ccid_lists)) {
1087                   log::error("StartStream: failed to set ASE configuration");
1088                   return false;
1089                 }
1090 
1091                 if (group_state == types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE ||
1092                     group_state == types::AseState::BTA_LE_AUDIO_ASE_STATE_CODEC_CONFIGURED) {
1093                   group->cig.GenerateCisIds(context_type);
1094 
1095                   std::vector<uint16_t> conn_handles;
1096                   for (uint8_t i = 0; i < (uint8_t)(group->cig.cises.size()); i++) {
1097                     conn_handles.push_back(iso_con_counter_++);
1098                   }
1099                   group->cig.AssignCisConnHandles(conn_handles);
1100                   for (LeAudioDevice* device = group->GetFirstActiveDevice(); device != nullptr;
1101                        device = group->GetNextActiveDevice(device)) {
1102                     if (!group->cig.AssignCisIds(device)) {
1103                       return false;
1104                     }
1105                     group->AssignCisConnHandlesToAses(device);
1106                   }
1107                 }
1108               }
1109 
1110               auto* stream_conf = &group->stream_conf;
1111 
1112               // Fake ASE configuration
1113               for (LeAudioDevice* device = group->GetFirstActiveDevice(); device != nullptr;
1114                    device = group->GetNextActiveDevice(device)) {
1115                 for (auto& ase : device->ases_) {
1116                   if (!ase.active) {
1117                     continue;
1118                   }
1119 
1120                   // And also skip the ase establishment procedure which should
1121                   // be tested as part of the state machine unit tests
1122                   ase.cis_state = types::CisState::CONNECTED;
1123                   ase.data_path_state = types::DataPathState::CONFIGURED;
1124                   ase.state = types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING;
1125                   ase.qos_preferences.pres_delay_min = 2500;
1126                   ase.qos_preferences.pres_delay_max = 2500;
1127                   ase.qos_preferences.preferred_pres_delay_min = 2500;
1128                   ase.qos_preferences.preferred_pres_delay_max = 2500;
1129                   auto core_config = ase.codec_config.params.GetAsCoreCodecConfig();
1130 
1131                   uint16_t cis_conn_hdl = ase.cis_conn_hdl;
1132 
1133                   /* Copied from state_machine.cc AddCisToStreamConfiguration */
1134                   if (ase.direction == bluetooth::le_audio::types::kLeAudioDirectionSource) {
1135                     auto iter = std::find_if(
1136                             stream_conf->stream_params.source.stream_config.stream_map.begin(),
1137                             stream_conf->stream_params.source.stream_config.stream_map.end(),
1138                             [cis_conn_hdl](auto& info) {
1139                               return cis_conn_hdl == info.stream_handle;
1140                             });
1141 
1142                     if (iter == stream_conf->stream_params.source.stream_config.stream_map.end()) {
1143                       stream_conf->stream_params.source.stream_config.stream_map.emplace_back(
1144                               stream_map_info(ase.cis_conn_hdl,
1145                                               *core_config.audio_channel_allocation, true));
1146 
1147                       stream_conf->stream_params.source.num_of_devices++;
1148                       stream_conf->stream_params.source.num_of_channels +=
1149                               ase.codec_config.channel_count_per_iso_stream;
1150                       stream_conf->stream_params.source.audio_channel_allocation |=
1151                               *core_config.audio_channel_allocation;
1152                       stream_conf->stream_params.source.stream_config.peer_delay_ms = 44;
1153 
1154                       if (stream_conf->stream_params.source.stream_config.sampling_frequency_hz ==
1155                           0) {
1156                         stream_conf->stream_params.source.stream_config.sampling_frequency_hz =
1157                                 core_config.GetSamplingFrequencyHz();
1158                       } else {
1159                         log::assert_that(stream_conf->stream_params.source.stream_config
1160                                                          .sampling_frequency_hz ==
1161                                                  core_config.GetSamplingFrequencyHz(),
1162                                          "StartStream: sample freq mismatch: {}!={}",
1163                                          stream_conf->stream_params.source.stream_config
1164                                                  .sampling_frequency_hz,
1165                                          core_config.GetSamplingFrequencyHz());
1166                       }
1167 
1168                       if (stream_conf->stream_params.source.stream_config.octets_per_codec_frame ==
1169                           0) {
1170                         stream_conf->stream_params.source.stream_config.octets_per_codec_frame =
1171                                 *core_config.octets_per_codec_frame;
1172                       } else {
1173                         log::assert_that(stream_conf->stream_params.source.stream_config
1174                                                          .octets_per_codec_frame ==
1175                                                  *core_config.octets_per_codec_frame,
1176                                          "StartStream: octets per frame mismatch: {}!={}",
1177                                          stream_conf->stream_params.source.stream_config
1178                                                  .octets_per_codec_frame,
1179                                          *core_config.octets_per_codec_frame);
1180                       }
1181 
1182                       if (stream_conf->stream_params.source.stream_config
1183                                   .codec_frames_blocks_per_sdu == 0) {
1184                         stream_conf->stream_params.source.stream_config
1185                                 .codec_frames_blocks_per_sdu =
1186                                 *core_config.codec_frames_blocks_per_sdu;
1187                         stream_conf->stream_params.source.stream_config.frame_duration_us =
1188                                 core_config.GetFrameDurationUs();
1189                       } else {
1190                         log::assert_that(stream_conf->stream_params.source.stream_config
1191                                                          .codec_frames_blocks_per_sdu ==
1192                                                  *core_config.codec_frames_blocks_per_sdu,
1193                                          "StartStream: codec_frames_blocks_per_sdu: {}!={}",
1194                                          stream_conf->stream_params.source.stream_config
1195                                                  .codec_frames_blocks_per_sdu,
1196                                          *core_config.codec_frames_blocks_per_sdu);
1197                       }
1198 
1199                       log::info(
1200                               "StartStream: Added Source Stream Configuration. CIS Connection "
1201                               "Handle: {}, Audio Channel Allocation: {}, Source Number "
1202                               "Of Devices: {}, Source Number Of Channels: {}",
1203                               ase.cis_conn_hdl, *core_config.audio_channel_allocation,
1204                               stream_conf->stream_params.source.num_of_devices,
1205                               stream_conf->stream_params.source.num_of_channels);
1206                     }
1207                   } else {
1208                     auto iter = std::find_if(
1209                             stream_conf->stream_params.sink.stream_config.stream_map.begin(),
1210                             stream_conf->stream_params.sink.stream_config.stream_map.end(),
1211                             [cis_conn_hdl](auto& info) {
1212                               return cis_conn_hdl == info.stream_handle;
1213                             });
1214 
1215                     if (iter == stream_conf->stream_params.sink.stream_config.stream_map.end()) {
1216                       stream_conf->stream_params.sink.stream_config.stream_map.emplace_back(
1217                               stream_map_info(ase.cis_conn_hdl,
1218                                               *core_config.audio_channel_allocation, true));
1219 
1220                       stream_conf->stream_params.sink.num_of_devices++;
1221                       stream_conf->stream_params.sink.num_of_channels +=
1222                               ase.codec_config.channel_count_per_iso_stream;
1223                       stream_conf->stream_params.sink.audio_channel_allocation |=
1224                               *core_config.audio_channel_allocation;
1225                       stream_conf->stream_params.sink.stream_config.peer_delay_ms = 44;
1226 
1227                       if (stream_conf->stream_params.sink.stream_config.sampling_frequency_hz ==
1228                           0) {
1229                         stream_conf->stream_params.sink.stream_config.sampling_frequency_hz =
1230                                 core_config.GetSamplingFrequencyHz();
1231                       } else {
1232                         log::assert_that(
1233                                 stream_conf->stream_params.sink.stream_config
1234                                                 .sampling_frequency_hz ==
1235                                         core_config.GetSamplingFrequencyHz(),
1236                                 "StartStream: sample freq mismatch: {}!={}",
1237                                 stream_conf->stream_params.sink.stream_config.sampling_frequency_hz,
1238                                 core_config.GetSamplingFrequencyHz());
1239                       }
1240 
1241                       if (stream_conf->stream_params.sink.stream_config.octets_per_codec_frame ==
1242                           0) {
1243                         stream_conf->stream_params.sink.stream_config.octets_per_codec_frame =
1244                                 *core_config.octets_per_codec_frame;
1245                       } else {
1246                         log::assert_that(stream_conf->stream_params.sink.stream_config
1247                                                          .octets_per_codec_frame ==
1248                                                  *core_config.octets_per_codec_frame,
1249                                          "StartStream: octets per frame mismatch: {}!={}",
1250                                          stream_conf->stream_params.sink.stream_config
1251                                                  .octets_per_codec_frame,
1252                                          *core_config.octets_per_codec_frame);
1253                       }
1254 
1255                       if (stream_conf->stream_params.sink.stream_config
1256                                   .codec_frames_blocks_per_sdu == 0) {
1257                         stream_conf->stream_params.sink.stream_config.codec_frames_blocks_per_sdu =
1258                                 *core_config.codec_frames_blocks_per_sdu;
1259                         stream_conf->stream_params.sink.stream_config.frame_duration_us =
1260                                 core_config.GetFrameDurationUs();
1261                       } else {
1262                         log::assert_that(stream_conf->stream_params.sink.stream_config
1263                                                          .codec_frames_blocks_per_sdu ==
1264                                                  *core_config.codec_frames_blocks_per_sdu,
1265                                          "StartStream: codec_frames_blocks_per_sdu: {}!={}",
1266                                          stream_conf->stream_params.sink.stream_config
1267                                                  .codec_frames_blocks_per_sdu,
1268                                          *core_config.codec_frames_blocks_per_sdu);
1269                       }
1270 
1271                       log::info(
1272                               "StartStream: Added Sink Stream Configuration. CIS Connection "
1273                               "Handle: "
1274                               "{}, Audio Channel Allocation: {}, Sink Number Of "
1275                               "Devices: {}, Sink Number Of Channels: {}",
1276                               ase.cis_conn_hdl, *core_config.audio_channel_allocation,
1277                               stream_conf->stream_params.sink.num_of_devices,
1278                               stream_conf->stream_params.sink.num_of_channels);
1279                     }
1280                   }
1281                 }
1282                 group->SetState(types::AseState::BTA_LE_AUDIO_ASE_STATE_QOS_CONFIGURED);
1283                 /* Assume CIG is created */
1284                 group->cig.SetState(bluetooth::le_audio::types::CigState::CREATED);
1285               }
1286 
1287               streaming_groups[group->group_id_] = group;
1288 
1289               if (stay_at_qos_config_in_start_stream) {
1290                 return true;
1291               }
1292 
1293               group->SetState(types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
1294               // Set streaming metadata
1295               for (LeAudioDevice* device = group->GetFirstActiveDevice(); device != nullptr;
1296                    device = group->GetNextActiveDevice(device)) {
1297                 for (auto& ase : device->ases_) {
1298                   if (!ase.active) {
1299                     continue;
1300                   }
1301                   group->SetStreamingMetadataContexts(metadata_context_types.get(ase.direction),
1302                                                       ase.direction);
1303                 }
1304               }
1305 
1306               do_in_main_thread(base::BindOnce(
1307                       [](int group_id, bluetooth::le_audio::LeAudioGroupStateMachine::Callbacks*
1308                                                state_machine_callbacks) {
1309                         state_machine_callbacks->StatusReportCb(group_id,
1310                                                                 GroupStreamStatus::STREAMING);
1311                       },
1312                       group->group_id_, base::Unretained(this->state_machine_callbacks_)));
1313               return true;
1314             });
1315 
1316     ON_CALL(mock_state_machine_, SuspendStream(_)).WillByDefault([this](LeAudioDeviceGroup* group) {
1317       // Fake ASE state
1318       for (LeAudioDevice* device = group->GetFirstDevice(); device != nullptr;
1319            device = group->GetNextDevice(device)) {
1320         for (auto& ase : device->ases_) {
1321           ase.cis_state = types::CisState::CONNECTED;
1322           ase.state = types::AseState::BTA_LE_AUDIO_ASE_STATE_QOS_CONFIGURED;
1323         }
1324       }
1325 
1326       // Inject the state
1327       group->SetTargetState(types::AseState::BTA_LE_AUDIO_ASE_STATE_QOS_CONFIGURED);
1328       group->ClearStreamingMetadataContexts();
1329       group->SetState(group->GetTargetState());
1330       state_machine_callbacks_->StatusReportCb(group->group_id_, GroupStreamStatus::SUSPENDED);
1331     });
1332 
1333     ON_CALL(mock_state_machine_, ProcessHciNotifAclDisconnected(_, _))
1334             .WillByDefault([this](LeAudioDeviceGroup* group, LeAudioDevice* leAudioDevice) {
1335               if (!group) {
1336                 return;
1337               }
1338 
1339               for (auto& ase : leAudioDevice->ases_) {
1340                 group->RemoveCisFromStreamIfNeeded(leAudioDevice, ase.cis_conn_hdl);
1341               }
1342 
1343               if (group->IsEmpty()) {
1344                 group->cig.SetState(bluetooth::le_audio::types::CigState::NONE);
1345                 InjectCigRemoved(group->group_id_);
1346               }
1347             });
1348 
1349     ON_CALL(mock_state_machine_, ProcessHciNotifCisDisconnected(_, _, _))
1350             .WillByDefault([this](LeAudioDeviceGroup* group, LeAudioDevice* leAudioDevice,
1351                                   const bluetooth::hci::iso_manager::cis_disconnected_evt* event) {
1352               if (!group) {
1353                 return;
1354               }
1355               auto ases_pair = leAudioDevice->GetAsesByCisConnHdl(event->cis_conn_hdl);
1356               if (ases_pair.sink) {
1357                 ases_pair.sink->cis_state = types::CisState::ASSIGNED;
1358                 ases_pair.sink->active = false;
1359               }
1360               if (ases_pair.source) {
1361                 ases_pair.source->active = false;
1362                 ases_pair.source->cis_state = types::CisState::ASSIGNED;
1363               }
1364 
1365               group->RemoveCisFromStreamIfNeeded(leAudioDevice, event->cis_conn_hdl);
1366 
1367               // When the device detaches from the stream we send again the state machine state to
1368               // stimulate the stream map update
1369               // see LeAudioGroupStateMachineImpl::SendStreamingStatusCbIfNeeded(group);
1370               if (!group->HaveAllCisesDisconnected() &&
1371                   (group->GetState() == types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING) &&
1372                   (group->GetTargetState() == types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING)) {
1373                 do_in_main_thread(base::BindOnce(
1374                         [](int group_id, bluetooth::le_audio::LeAudioGroupStateMachine::Callbacks*
1375                                                  state_machine_callbacks) {
1376                           state_machine_callbacks->StatusReportCb(group_id,
1377                                                                   GroupStreamStatus::STREAMING);
1378                         },
1379                         group->group_id_, base::Unretained(this->state_machine_callbacks_)));
1380               }
1381             });
1382 
1383     ON_CALL(mock_state_machine_, StopStream(_)).WillByDefault([this](LeAudioDeviceGroup* group) {
1384       for (LeAudioDevice* device = group->GetFirstDevice(); device != nullptr;
1385            device = group->GetNextDevice(device)) {
1386         /* Invalidate stream configuration if needed */
1387         auto* stream_conf = &group->stream_conf;
1388         if (!stream_conf->stream_params.sink.stream_config.stream_map.empty() ||
1389             !stream_conf->stream_params.source.stream_config.stream_map.empty()) {
1390           stream_conf->stream_params.sink.stream_config.stream_map.erase(
1391                   std::remove_if(stream_conf->stream_params.sink.stream_config.stream_map.begin(),
1392                                  stream_conf->stream_params.sink.stream_config.stream_map.end(),
1393                                  [device, &stream_conf](auto& info) {
1394                                    auto ases = device->GetAsesByCisConnHdl(info.stream_handle);
1395 
1396                                    log::info(
1397                                            ", sink ase to delete. Cis handle: {}, ase "
1398                                            "pointer: {}",
1399                                            (int)(info.stream_handle), std::format_ptr(+ases.sink));
1400                                    if (ases.sink) {
1401                                      stream_conf->stream_params.sink.num_of_devices--;
1402                                      stream_conf->stream_params.sink.num_of_channels -=
1403                                              ases.sink->codec_config.channel_count_per_iso_stream;
1404 
1405                                      log::info(
1406                                              "Sink Number Of Devices: {}, Sink Number Of "
1407                                              "Channels: {}",
1408                                              stream_conf->stream_params.sink.num_of_devices,
1409                                              stream_conf->stream_params.sink.num_of_channels);
1410                                    }
1411                                    return ases.sink;
1412                                  }),
1413                   stream_conf->stream_params.sink.stream_config.stream_map.end());
1414 
1415           stream_conf->stream_params.source.stream_config.stream_map.erase(
1416                   std::remove_if(stream_conf->stream_params.source.stream_config.stream_map.begin(),
1417                                  stream_conf->stream_params.source.stream_config.stream_map.end(),
1418                                  [device, &stream_conf](auto& info) {
1419                                    auto ases = device->GetAsesByCisConnHdl(info.stream_handle);
1420 
1421                                    log::info(
1422                                            ", source to delete. Cis handle: {}, ase pointer: "
1423                                            "{}",
1424                                            (int)(info.stream_handle),
1425                                            std::format_ptr(+ases.source));
1426                                    if (ases.source) {
1427                                      stream_conf->stream_params.source.num_of_devices--;
1428                                      stream_conf->stream_params.source.num_of_channels -=
1429                                              ases.source->codec_config.channel_count_per_iso_stream;
1430 
1431                                      log::info(
1432                                              ", Source Number Of Devices: {}, Source Number "
1433                                              "Of Channels: {}",
1434                                              stream_conf->stream_params.source.num_of_devices,
1435                                              stream_conf->stream_params.source.num_of_channels);
1436                                    }
1437                                    return ases.source;
1438                                  }),
1439                   stream_conf->stream_params.source.stream_config.stream_map.end());
1440         }
1441 
1442         group->ClearStreamingMetadataContexts();
1443         for (auto& ase : device->ases_) {
1444           group->cig.UnassignCis(device, ase.cis_conn_hdl);
1445 
1446           ase.cis_state = types::CisState::IDLE;
1447           ase.data_path_state = types::DataPathState::IDLE;
1448           ase.active = false;
1449           ase.state = types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE;
1450           ase.cis_id = 0;
1451           ase.cis_conn_hdl = bluetooth::le_audio::kInvalidCisConnHandle;
1452         }
1453       }
1454 
1455       // Inject the state
1456       group->SetTargetState(types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE);
1457       group->SetState(types::AseState::BTA_LE_AUDIO_ASE_STATE_RELEASING);
1458       state_machine_callbacks_->StatusReportCb(group->group_id_, GroupStreamStatus::RELEASING);
1459 
1460       if (stay_at_releasing_stop_stream) {
1461         log::info("StopStream {} -> stay in Releasing state", group->group_id_);
1462         return;
1463       }
1464       group->SetState(group->GetTargetState());
1465 
1466       do_in_main_thread(base::BindOnce(
1467               [](bluetooth::le_audio::LeAudioGroupStateMachine::Callbacks* cb, int group_id) {
1468                 cb->StatusReportCb(group_id, GroupStreamStatus::IDLE);
1469               },
1470               state_machine_callbacks_, group->group_id_));
1471     });
1472   }
1473 
SetUp()1474   void SetUp() override {
1475     __android_log_set_minimum_priority(ANDROID_LOG_VERBOSE);
1476     com::android::bluetooth::flags::provider_->reset_flags();
1477 
1478     init_message_loop_thread();
1479     reset_mock_function_count_map();
1480     hci::testing::mock_controller_ =
1481             std::make_unique<NiceMock<bluetooth::hci::testing::MockControllerInterface>>();
1482     ON_CALL(*hci::testing::mock_controller_, SupportsBleConnectedIsochronousStreamCentral)
1483             .WillByDefault(Return(true));
1484     ON_CALL(*hci::testing::mock_controller_, SupportsBleConnectedIsochronousStreamPeripheral)
1485             .WillByDefault(Return(true));
1486     ON_CALL(*hci::testing::mock_controller_, SupportsBle2mPhy).WillByDefault(Return(true));
1487     bluetooth::manager::SetMockBtmInterface(&mock_btm_interface_);
1488     gatt::SetMockBtaGattInterface(&mock_gatt_interface_);
1489     gatt::SetMockBtaGattQueue(&mock_gatt_queue_);
1490     bluetooth::storage::SetMockBtifStorageInterface(&mock_btif_storage_);
1491 
1492     iso_manager_ = bluetooth::hci::IsoManager::GetInstance();
1493     ASSERT_NE(iso_manager_, nullptr);
1494     iso_manager_->Start();
1495 
1496     mock_iso_manager_ = MockIsoManager::GetInstance();
1497     ON_CALL(*mock_iso_manager_, RegisterCigCallbacks(_)).WillByDefault(SaveArg<0>(&cig_callbacks_));
1498 
1499     ON_CALL(mock_btm_interface_, IsDeviceBonded(_, _)).WillByDefault(DoAll(Return(true)));
1500 
1501     // Required since we call OnAudioDataReady()
1502     const auto codec_location = ::bluetooth::le_audio::types::CodecLocation::HOST;
1503 
1504     SetUpMockAudioHal();
1505     SetUpMockGroups();
1506     SetUpMockGatt();
1507     SetUpMockCodecManager(codec_location);
1508 
1509     stay_at_qos_config_in_start_stream = false;
1510     stay_at_releasing_stop_stream = false;
1511 
1512     available_snk_context_types_ = 0xffff;
1513     available_src_context_types_ = 0xffff;
1514     supported_snk_context_types_ = 0xffff;
1515     supported_src_context_types_ = 0xffff;
1516 
1517     empty_source_pack_ = false;
1518     empty_sink_pack_ = false;
1519 
1520     bluetooth::le_audio::AudioSetConfigurationProvider::Initialize(codec_location);
1521     ASSERT_FALSE(LeAudioClient::IsLeAudioClientRunning());
1522   }
1523 
SetUpMockCodecManager(types::CodecLocation location)1524   void SetUpMockCodecManager(types::CodecLocation location) {
1525     codec_manager_ = bluetooth::le_audio::CodecManager::GetInstance();
1526     ASSERT_NE(codec_manager_, nullptr);
1527     std::vector<bluetooth::le_audio::btle_audio_codec_config_t> mock_offloading_preference(0);
1528     codec_manager_->Start(mock_offloading_preference);
1529     mock_codec_manager_ = MockCodecManager::GetInstance();
1530     ASSERT_NE((void*)mock_codec_manager_, (void*)codec_manager_);
1531     ASSERT_NE(mock_codec_manager_, nullptr);
1532     ON_CALL(*mock_codec_manager_, GetCodecLocation()).WillByDefault(Return(location));
1533     ON_CALL(*mock_codec_manager_, UpdateActiveUnicastAudioHalClient(_, _, _))
1534             .WillByDefault(Return(true));
1535     ON_CALL(*mock_codec_manager_, UpdateActiveBroadcastAudioHalClient(_, _))
1536             .WillByDefault(Return(true));
1537     // Turn on the dual bidir SWB support
1538     ON_CALL(*mock_codec_manager_, IsDualBiDirSwbSupported).WillByDefault(Return(true));
1539     // Regardless of the codec location, return all the possible configurations
1540     ON_CALL(*mock_codec_manager_, GetCodecConfig)
1541             .WillByDefault(Invoke([](const CodecManager::UnicastConfigurationRequirements&
1542                                              requirements,
1543                                      CodecManager::UnicastConfigurationProvider provider) {
1544               auto filtered = *le_audio::AudioSetConfigurationProvider::Get()->GetConfigurations(
1545                       requirements.audio_context_type);
1546               // Filter out the dual bidir SWB configurations
1547               if (!bluetooth::le_audio::CodecManager::GetInstance()->IsDualBiDirSwbSupported()) {
1548                 filtered.erase(std::remove_if(filtered.begin(), filtered.end(),
1549                                               [](auto const& el) {
1550                                                 if (el->confs.source.empty()) {
1551                                                   return false;
1552                                                 }
1553                                                 return AudioSetConfigurationProvider::Get()
1554                                                         ->CheckConfigurationIsDualBiDirSwb(*el);
1555                                               }),
1556                                filtered.end());
1557               }
1558               return provider(requirements, &filtered);
1559             }));
1560   }
1561 
TearDown()1562   void TearDown() override {
1563     // WARNING: Message loop cleanup should wait for all the 'till now' scheduled calls
1564     // so it should be called right at the very begginning of teardown.
1565     cleanup_message_loop_thread();
1566 
1567     if (is_audio_unicast_source_acquired) {
1568       if (unicast_source_hal_cb_ != nullptr) {
1569         EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop).Times(1);
1570       }
1571       EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(1);
1572     }
1573 
1574     if (is_audio_unicast_sink_acquired) {
1575       if (unicast_sink_hal_cb_ != nullptr) {
1576         EXPECT_CALL(*mock_le_audio_sink_hal_client_, Stop).Times(1);
1577       }
1578       EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(1);
1579     }
1580 
1581     // This is required since Stop() and Cleanup() may trigger some callbacks or
1582     // drop unique pointers to mocks we have raw pointer for and we want to
1583     // verify them all.
1584     Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
1585 
1586     if (LeAudioClient::IsLeAudioClientRunning()) {
1587       EXPECT_CALL(mock_gatt_interface_, AppDeregister(gatt_if)).Times(1);
1588       LeAudioClient::Cleanup();
1589       ASSERT_FALSE(LeAudioClient::IsLeAudioClientRunning());
1590     }
1591 
1592     owned_mock_le_audio_sink_hal_client_.reset();
1593     owned_mock_le_audio_source_hal_client_.reset();
1594 
1595     if (bluetooth::le_audio::AudioSetConfigurationProvider::Get()) {
1596       bluetooth::le_audio::AudioSetConfigurationProvider::Cleanup();
1597     }
1598 
1599     iso_manager_->Stop();
1600     hci::testing::mock_controller_.reset();
1601   }
1602 
1603 protected:
1604   class MockDeviceWrapper {
1605     class IGattHandlers {
1606     public:
1607       // IGattHandlers() = default;
1608       virtual ~IGattHandlers() = default;
1609       virtual std::pair<GattStatus, std::vector<uint8_t>> OnGetCharacteristicValue(
1610               uint16_t handle) = 0;
1611       virtual void OnWriteCharacteristic(uint16_t handle, std::vector<uint8_t> value,
1612                                          tGATT_WRITE_TYPE write_type, GATT_WRITE_OP_CB cb,
1613                                          void* cb_data) = 0;
1614     };
1615 
1616   public:
1617     struct csis_mock : public IGattHandlers {
1618       uint16_t start = 0;
1619       uint16_t end = 0;
1620       uint16_t sirk_char = 0;
1621       uint16_t sirk_ccc = 0;
1622       uint16_t size_char = 0;
1623       uint16_t size_ccc = 0;
1624       uint16_t lock_char = 0;
1625       uint16_t lock_ccc = 0;
1626       uint16_t rank_char = 0;
1627 
1628       int rank = 0;
1629       int size = 0;
1630 
1631       MOCK_METHOD((std::pair<GattStatus, std::vector<uint8_t>>), OnGetCharacteristicValue,
1632                   (uint16_t handle), (override));
1633       MOCK_METHOD((void), OnWriteCharacteristic,
1634                   (uint16_t handle, std::vector<uint8_t> value, tGATT_WRITE_TYPE write_type,
1635                    GATT_WRITE_OP_CB cb, void* cb_data),
1636                   (override));
1637     };
1638 
1639     struct cas_mock : public IGattHandlers {
1640       uint16_t start = 0;
1641       uint16_t end = 0;
1642       uint16_t csis_include = 0;
1643 
1644       MOCK_METHOD((std::pair<GattStatus, std::vector<uint8_t>>), OnGetCharacteristicValue,
1645                   (uint16_t handle), (override));
1646       MOCK_METHOD((void), OnWriteCharacteristic,
1647                   (uint16_t handle, std::vector<uint8_t> value, tGATT_WRITE_TYPE write_type,
1648                    GATT_WRITE_OP_CB cb, void* cb_data),
1649                   (override));
1650     };
1651 
1652     struct pacs_mock : public IGattHandlers {
1653       uint16_t start = 0;
1654       uint16_t sink_pac_char = 0;
1655       uint16_t sink_pac_ccc = 0;
1656       uint16_t sink_audio_loc_char = 0;
1657       uint16_t sink_audio_loc_ccc = 0;
1658       uint16_t source_pac_char = 0;
1659       uint16_t source_pac_ccc = 0;
1660       uint16_t source_audio_loc_char = 0;
1661       uint16_t source_audio_loc_ccc = 0;
1662       uint16_t avail_contexts_char = 0;
1663       uint16_t avail_contexts_ccc = 0;
1664       uint16_t supp_contexts_char = 0;
1665       uint16_t supp_contexts_ccc = 0;
1666       uint16_t end = 0;
1667 
1668       MOCK_METHOD((std::pair<GattStatus, std::vector<uint8_t>>), OnGetCharacteristicValue,
1669                   (uint16_t handle), (override));
1670       MOCK_METHOD((void), OnWriteCharacteristic,
1671                   (uint16_t handle, std::vector<uint8_t> value, tGATT_WRITE_TYPE write_type,
1672                    GATT_WRITE_OP_CB cb, void* cb_data),
1673                   (override));
1674     };
1675 
1676     struct ascs_mock : public IGattHandlers {
1677       uint16_t start = 0;
1678       uint16_t sink_ase_char[max_num_of_ases] = {0};
1679       uint16_t sink_ase_ccc[max_num_of_ases] = {0};
1680       uint16_t sink_ase_ccc_val[max_num_of_ases] = {0};
1681       uint16_t source_ase_char[max_num_of_ases] = {0};
1682       uint16_t source_ase_ccc[max_num_of_ases] = {0};
1683       uint16_t source_ase_ccc_val[max_num_of_ases] = {0};
1684       uint16_t ctp_char = 0;
1685       uint16_t ctp_ccc = 0;
1686       uint16_t ctp_ccc_val = 0;
1687       uint16_t end = 0;
1688 
1689       MOCK_METHOD((std::pair<GattStatus, std::vector<uint8_t>>), OnGetCharacteristicValue,
1690                   (uint16_t handle), (override));
1691       MOCK_METHOD((void), OnWriteCharacteristic,
1692                   (uint16_t handle, std::vector<uint8_t> value, tGATT_WRITE_TYPE write_type,
1693                    GATT_WRITE_OP_CB cb, void* cb_data),
1694                   (override));
1695     };
1696 
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)1697     MockDeviceWrapper(RawAddress addr, const std::list<gatt::Service>& services,
1698                       std::unique_ptr<NiceMock<MockDeviceWrapper::csis_mock>> csis,
1699                       std::unique_ptr<NiceMock<MockDeviceWrapper::cas_mock>> cas,
1700                       std::unique_ptr<NiceMock<MockDeviceWrapper::ascs_mock>> ascs,
1701                       std::unique_ptr<NiceMock<MockDeviceWrapper::pacs_mock>> pacs)
1702         : addr(addr) {
1703       this->services = services;
1704       this->csis = std::move(csis);
1705       this->cas = std::move(cas);
1706       this->ascs = std::move(ascs);
1707       this->pacs = std::move(pacs);
1708     }
1709 
~MockDeviceWrapper()1710     ~MockDeviceWrapper() {
1711       Mock::VerifyAndClearExpectations(csis.get());
1712       Mock::VerifyAndClearExpectations(cas.get());
1713       Mock::VerifyAndClearExpectations(ascs.get());
1714       Mock::VerifyAndClearExpectations(pacs.get());
1715     }
1716 
1717     RawAddress addr;
1718     bool connected = false;
1719 
1720     // A list of services and their useful params
1721     std::list<gatt::Service> services;
1722     std::unique_ptr<csis_mock> csis;
1723     std::unique_ptr<cas_mock> cas;
1724     std::unique_ptr<ascs_mock> ascs;
1725     std::unique_ptr<pacs_mock> pacs;
1726   };
1727 
SyncOnMainLoop()1728   void SyncOnMainLoop() {
1729     // Wait for the main loop to flush
1730     // WARNING: Not tested with Timers pushing periodic tasks to the main loop
1731     while (num_async_tasks > 0) {
1732     }
1733   }
1734 
ConnectLeAudio(const RawAddress & address,bool isEncrypted=true,bool expect_connected_event=true)1735   void ConnectLeAudio(const RawAddress& address, bool isEncrypted = true,
1736                       bool expect_connected_event = true) {
1737     // by default indicate link as encrypted
1738     ON_CALL(mock_btm_interface_, BTM_IsEncrypted(address, _))
1739             .WillByDefault(DoAll(Return(isEncrypted)));
1740 
1741     ON_CALL(mock_btm_interface_, IsDeviceBonded(address, _)).WillByDefault(DoAll(Return(true)));
1742 
1743     EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, address, BTM_BLE_DIRECT_CONNECTION, _))
1744             .Times(1);
1745 
1746     /* If connected event is not expected to arrive, don't test those two below
1747      */
1748     if (expect_connected_event) {
1749       EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, address, false));
1750       EXPECT_CALL(mock_gatt_interface_,
1751                   Open(gatt_if, address, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _))
1752               .Times(1);
1753     }
1754 
1755     do_in_main_thread(base::BindOnce(&LeAudioClient::Connect,
1756                                      base::Unretained(LeAudioClient::Get()), address));
1757 
1758     SyncOnMainLoop();
1759     Mock::VerifyAndClearExpectations(&mock_btm_interface_);
1760     Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
1761     Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
1762   }
1763 
DisconnectLeAudioWithGattClose(const RawAddress & address,uint16_t conn_id,tGATT_DISCONN_REASON=GATT_CONN_TERMINATE_LOCAL_HOST)1764   void DisconnectLeAudioWithGattClose(
1765           const RawAddress& address, uint16_t conn_id,
1766           tGATT_DISCONN_REASON /*reason*/ = GATT_CONN_TERMINATE_LOCAL_HOST) {
1767     EXPECT_CALL(mock_audio_hal_client_callbacks_,
1768                 OnConnectionState(ConnectionState::DISCONNECTED, address))
1769             .Times(1);
1770 
1771     // For test purpose use the acl handle same as conn_id
1772     ON_CALL(mock_btm_interface_, GetHCIConnHandle(address, _))
1773             .WillByDefault([conn_id](RawAddress const& /*bd_addr*/, tBT_TRANSPORT /*transport*/) {
1774               return conn_id;
1775             });
1776     EXPECT_CALL(mock_btm_interface_, AclDisconnectFromHandle(conn_id, _)).Times(0);
1777     EXPECT_CALL(mock_gatt_interface_, Close(conn_id)).Times(1);
1778 
1779     do_in_main_thread(base::Bind(&LeAudioClient::Disconnect, base::Unretained(LeAudioClient::Get()),
1780                                  address));
1781     SyncOnMainLoop();
1782     Mock::VerifyAndClearExpectations(&mock_btm_interface_);
1783     Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
1784     Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
1785   }
1786 
DisconnectLeAudioWithAclClose(const RawAddress & address,uint16_t conn_id,tGATT_DISCONN_REASON reason=GATT_CONN_TERMINATE_LOCAL_HOST)1787   void DisconnectLeAudioWithAclClose(const RawAddress& address, uint16_t conn_id,
1788                                      tGATT_DISCONN_REASON reason = GATT_CONN_TERMINATE_LOCAL_HOST) {
1789     EXPECT_CALL(mock_audio_hal_client_callbacks_,
1790                 OnConnectionState(ConnectionState::DISCONNECTED, address))
1791             .Times(1);
1792 
1793     // For test purpose use the acl handle same as conn_id
1794     ON_CALL(mock_btm_interface_, GetHCIConnHandle(address, _))
1795             .WillByDefault([conn_id](RawAddress const& /*bd_addr*/, tBT_TRANSPORT /*transport*/) {
1796               return conn_id;
1797             });
1798     EXPECT_CALL(mock_btm_interface_, AclDisconnectFromHandle(conn_id, _))
1799             .WillOnce([this, &reason](uint16_t handle, tHCI_STATUS /*rs*/) {
1800               InjectDisconnectedEvent(handle, reason);
1801             });
1802     EXPECT_CALL(mock_gatt_interface_, Close(conn_id)).Times(0);
1803 
1804     do_in_main_thread(base::Bind(&LeAudioClient::Disconnect, base::Unretained(LeAudioClient::Get()),
1805                                  address));
1806     SyncOnMainLoop();
1807     Mock::VerifyAndClearExpectations(&mock_btm_interface_);
1808     Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
1809     Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
1810   }
1811 
DisconnectLeAudioNoDisconnectedEvtExpected(const RawAddress & address,uint16_t conn_id)1812   void DisconnectLeAudioNoDisconnectedEvtExpected(const RawAddress& address, uint16_t conn_id) {
1813     EXPECT_CALL(mock_gatt_interface_, Close(conn_id)).Times(0);
1814     EXPECT_CALL(mock_btm_interface_, AclDisconnectFromHandle(conn_id, _)).Times(1);
1815     do_in_main_thread(base::BindOnce(&LeAudioClient::Disconnect,
1816                                      base::Unretained(LeAudioClient::Get()), address));
1817     SyncOnMainLoop();
1818     Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
1819     Mock::VerifyAndClearExpectations(&mock_btm_interface_);
1820   }
1821 
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)1822   void ConnectCsisDevice(const RawAddress& addr, uint16_t conn_id, uint32_t sink_audio_allocation,
1823                          uint32_t source_audio_allocation, uint8_t group_size, int group_id,
1824                          uint8_t rank, bool connect_through_csis = false, bool new_device = true) {
1825     SetSampleDatabaseEarbudsValid(conn_id, addr, sink_audio_allocation, source_audio_allocation,
1826                                   default_channel_cnt, default_channel_cnt,
1827                                   0x0034, /* source sample freq 16/24k/32hz */
1828                                   true,   /*add_csis*/
1829                                   true,   /*add_cas*/
1830                                   true,   /*add_pacs*/
1831                                   true,   /*add_ascs*/
1832                                   group_size, rank);
1833     EXPECT_CALL(mock_audio_hal_client_callbacks_,
1834                 OnConnectionState(ConnectionState::CONNECTED, addr))
1835             .Times(1);
1836 
1837     if (new_device) {
1838       EXPECT_CALL(mock_audio_hal_client_callbacks_,
1839                   OnGroupNodeStatus(addr, group_id, GroupNodeStatus::ADDED))
1840               .Times(1);
1841     }
1842 
1843     if (connect_through_csis) {
1844       // Add it the way CSIS would do: add to group and then connect
1845       do_in_main_thread(base::BindOnce(&LeAudioClient::GroupAddNode,
1846                                        base::Unretained(LeAudioClient::Get()), group_id, addr));
1847       ConnectLeAudio(addr);
1848     } else {
1849       // The usual connect
1850       // Since device has CSIS, lets add it here to groups already now
1851       groups[addr] = group_id;
1852       ConnectLeAudio(addr);
1853       InjectGroupDeviceAdded(addr, group_id);
1854     }
1855   }
1856 
ConnectNonCsisDevice(const RawAddress & addr,uint16_t conn_id,uint32_t sink_audio_allocation,uint32_t source_audio_allocation)1857   void ConnectNonCsisDevice(const RawAddress& addr, uint16_t conn_id,
1858                             uint32_t sink_audio_allocation, uint32_t source_audio_allocation) {
1859     SetSampleDatabaseEarbudsValid(conn_id, addr, sink_audio_allocation, source_audio_allocation,
1860                                   default_channel_cnt, default_channel_cnt, 0x0004,
1861                                   /* source sample freq 16khz */ false, /*add_csis*/
1862                                   true,                                 /*add_cas*/
1863                                   true,                                 /*add_pacs*/
1864                                   true,                                 /*add_ascs*/
1865                                   0, 0);
1866     EXPECT_CALL(mock_audio_hal_client_callbacks_,
1867                 OnConnectionState(ConnectionState::CONNECTED, addr))
1868             .Times(1);
1869 
1870     ConnectLeAudio(addr);
1871   }
1872 
UpdateLocalSourceMetadata(std::vector<struct playback_track_metadata> tracks,bool reconfigure_existing_stream=false)1873   void UpdateLocalSourceMetadata(std::vector<struct playback_track_metadata> tracks,
1874                                  bool reconfigure_existing_stream = false) {
1875     std::vector<playback_track_metadata_v7> tracks_vec;
1876     tracks_vec.reserve(tracks.size());
1877     for (const auto& track : tracks) {
1878       playback_track_metadata_v7 desc_track = {
1879               .base =
1880                       {
1881                               .usage = static_cast<audio_usage_t>(track.usage),
1882                               .content_type = static_cast<audio_content_type_t>(track.content_type),
1883                               .gain = track.gain,
1884                       },
1885       };
1886       if (test_tags_ptr_) {
1887         memcpy(desc_track.tags, test_tags_ptr_, strlen(test_tags_ptr_));
1888       }
1889 
1890       tracks_vec.push_back(desc_track);
1891     }
1892 
1893     ASSERT_NE(nullptr, mock_le_audio_source_hal_client_);
1894     /* Local Source may reconfigure once the metadata is updated */
1895     if (reconfigure_existing_stream) {
1896       Expectation reconfigure =
1897               EXPECT_CALL(*mock_le_audio_source_hal_client_, SuspendedForReconfiguration())
1898                       .Times(1);
1899       EXPECT_CALL(*mock_le_audio_source_hal_client_, CancelStreamingRequest()).Times(1);
1900       EXPECT_CALL(*mock_le_audio_source_hal_client_, ReconfigurationComplete())
1901               .Times(1)
1902               .After(reconfigure);
1903     } else {
1904       EXPECT_CALL(*mock_le_audio_source_hal_client_, SuspendedForReconfiguration()).Times(0);
1905       EXPECT_CALL(*mock_le_audio_source_hal_client_, ReconfigurationComplete()).Times(0);
1906     }
1907 
1908     ASSERT_NE(unicast_source_hal_cb_, nullptr);
1909     unicast_source_hal_cb_->OnAudioMetadataUpdate(std::move(tracks_vec), DsaMode::DISABLED);
1910   }
1911 
UpdateLocalSourceMetadata(audio_usage_t usage,audio_content_type_t content_type,bool reconfigure_existing_stream=false)1912   void UpdateLocalSourceMetadata(audio_usage_t usage, audio_content_type_t content_type,
1913                                  bool reconfigure_existing_stream = false) {
1914     std::vector<struct playback_track_metadata> tracks = {
1915             {{AUDIO_USAGE_UNKNOWN, AUDIO_CONTENT_TYPE_UNKNOWN, 0},
1916              {AUDIO_USAGE_UNKNOWN, AUDIO_CONTENT_TYPE_UNKNOWN, 0}}};
1917 
1918     tracks[0].usage = usage;
1919     tracks[0].content_type = content_type;
1920     UpdateLocalSourceMetadata(tracks, reconfigure_existing_stream);
1921   }
1922 
UpdateLocalSinkMetadata(std::optional<audio_source_t> audio_source,std::optional<audio_source_t> additional_audio_source=std::nullopt)1923   void UpdateLocalSinkMetadata(
1924           std::optional<audio_source_t> audio_source,
1925           std::optional<audio_source_t> additional_audio_source = std::nullopt) {
1926     std::vector<struct record_track_metadata> tracks = {
1927             {{AUDIO_SOURCE_INVALID, 0.5, AUDIO_DEVICE_NONE, "00:11:22:33:44:55"}}};
1928 
1929     if (audio_source.has_value() && (audio_source.value() != AUDIO_SOURCE_INVALID)) {
1930       tracks.push_back(
1931               {audio_source.value(), 0.7, AUDIO_DEVICE_OUT_BLE_HEADSET, "AA:BB:CC:DD:EE:FF"});
1932     }
1933     if (additional_audio_source.has_value() &&
1934         (additional_audio_source.value() != AUDIO_SOURCE_INVALID)) {
1935       tracks.push_back({additional_audio_source.value(), 0.7, AUDIO_DEVICE_OUT_BLE_HEADSET,
1936                         "AA:BB:CC:DD:EE:FF"});
1937     }
1938 
1939     // Call the callback if we have added a valid track or we explicitly want to send no tracks
1940     if (!audio_source.has_value() || tracks.size() > 1) {
1941       std::vector<record_track_metadata_v7> tracks_vec;
1942       tracks_vec.reserve(tracks.size());
1943       for (const auto& track : tracks) {
1944         record_track_metadata_v7 desc_track = {
1945                 .base =
1946                         {
1947                                 .source = static_cast<audio_source_t>(track.source),
1948                                 .gain = track.gain,
1949                                 .dest_device = static_cast<audio_devices_t>(track.dest_device),
1950                         },
1951         };
1952 
1953         snprintf(desc_track.base.dest_device_address, AUDIO_DEVICE_MAX_ADDRESS_LEN, "%s",
1954                  track.dest_device_address);
1955         tracks_vec.push_back(desc_track);
1956       }
1957 
1958       ASSERT_NE(nullptr, unicast_sink_hal_cb_);
1959       unicast_sink_hal_cb_->OnAudioMetadataUpdate(std::move(tracks_vec));
1960     }
1961   }
1962 
LocalAudioSourceSuspend(void)1963   void LocalAudioSourceSuspend(void) {
1964     ASSERT_NE(unicast_source_hal_cb_, nullptr);
1965     unicast_source_hal_cb_->OnAudioSuspend();
1966     SyncOnMainLoop();
1967   }
1968 
LocalAudioSourceResume(bool expected_confirmation=true,bool expected_cancel=false)1969   void LocalAudioSourceResume(bool expected_confirmation = true, bool expected_cancel = false) {
1970     ASSERT_NE(nullptr, mock_le_audio_source_hal_client_);
1971     if (expected_confirmation) {
1972       EXPECT_CALL(*mock_le_audio_source_hal_client_, ConfirmStreamingRequest()).Times(1);
1973     }
1974 
1975     if (expected_cancel) {
1976       EXPECT_CALL(*mock_le_audio_source_hal_client_, CancelStreamingRequest()).Times(1);
1977     }
1978 
1979     do_in_main_thread(base::BindOnce(
1980             [](LeAudioSourceAudioHalClient::Callbacks* cb) {
1981               if (cb) {
1982                 cb->OnAudioResume();
1983               }
1984             },
1985             unicast_source_hal_cb_));
1986 
1987     SyncOnMainLoop();
1988     if (expected_confirmation || expected_cancel) {
1989       Mock::VerifyAndClearExpectations(&*mock_le_audio_source_hal_client_);
1990     }
1991   }
1992 
LocalAudioSinkSuspend(void)1993   void LocalAudioSinkSuspend(void) {
1994     ASSERT_NE(unicast_sink_hal_cb_, nullptr);
1995     unicast_sink_hal_cb_->OnAudioSuspend();
1996     SyncOnMainLoop();
1997   }
1998 
LocalAudioSinkResume(void)1999   void LocalAudioSinkResume(void) {
2000     ASSERT_NE(unicast_sink_hal_cb_, nullptr);
2001     do_in_main_thread(
2002             base::BindOnce([](LeAudioSinkAudioHalClient::Callbacks* cb) { cb->OnAudioResume(); },
2003                            unicast_sink_hal_cb_));
2004 
2005     SyncOnMainLoop();
2006     Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
2007   }
2008 
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)2009   void StartStreaming(audio_usage_t usage, audio_content_type_t content_type, int /*group_id*/,
2010                       audio_source_t audio_source = AUDIO_SOURCE_INVALID,
2011                       bool reconfigure_existing_stream = false,
2012                       bool expected_resume_confirmation = true) {
2013     ASSERT_NE(unicast_source_hal_cb_, nullptr);
2014 
2015     UpdateLocalSourceMetadata(usage, content_type, reconfigure_existing_stream);
2016     UpdateLocalSinkMetadata(audio_source);
2017 
2018     /* Stream has been automatically restarted on UpdateLocalSourceMetadata */
2019     if (reconfigure_existing_stream) {
2020       return;
2021     }
2022 
2023     LocalAudioSourceResume(expected_resume_confirmation);
2024     SyncOnMainLoop();
2025     Mock::VerifyAndClearExpectations(&mock_state_machine_);
2026 
2027     if (usage == AUDIO_USAGE_VOICE_COMMUNICATION || audio_source != AUDIO_SOURCE_INVALID) {
2028       ASSERT_NE(unicast_sink_hal_cb_, nullptr);
2029       do_in_main_thread(
2030               base::BindOnce([](LeAudioSinkAudioHalClient::Callbacks* cb) { cb->OnAudioResume(); },
2031                              unicast_sink_hal_cb_));
2032     }
2033     SyncOnMainLoop();
2034   }
2035 
StopStreaming(int,bool suspend_source=false)2036   void StopStreaming(int /*group_id*/, bool suspend_source = false) {
2037     ASSERT_NE(unicast_source_hal_cb_, nullptr);
2038 
2039     /* TODO We should have a way to confirm Stop() otherwise, audio framework
2040      * might have different state that it is in the le_audio code - as tearing
2041      * down CISes might take some time
2042      */
2043     /* It's enough to call only one resume even if it'll be bi-directional
2044      * streaming. First suspend will trigger GroupStop.
2045      *
2046      * There is no - 'only source receiver' scenario (e.g. single microphone).
2047      * If there will be such test oriented scenario, such resume choose logic
2048      * should be applied.
2049      */
2050     unicast_source_hal_cb_->OnAudioSuspend();
2051 
2052     if (suspend_source) {
2053       ASSERT_NE(unicast_sink_hal_cb_, nullptr);
2054       unicast_sink_hal_cb_->OnAudioSuspend();
2055     }
2056     SyncOnMainLoop();
2057   }
2058 
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)2059   void set_sample_database(uint16_t conn_id, RawAddress addr,
2060                            std::unique_ptr<NiceMock<MockDeviceWrapper::csis_mock>> csis,
2061                            std::unique_ptr<NiceMock<MockDeviceWrapper::cas_mock>> cas,
2062                            std::unique_ptr<NiceMock<MockDeviceWrapper::ascs_mock>> ascs,
2063                            std::unique_ptr<NiceMock<MockDeviceWrapper::pacs_mock>> pacs) {
2064     gatt::DatabaseBuilder bob;
2065 
2066     /* Generic Access Service */
2067     bob.AddService(0x0001, 0x0003, Uuid::From16Bit(0x1800), true);
2068     /* Device Name Char. */
2069     bob.AddCharacteristic(0x0002, 0x0003, Uuid::From16Bit(0x2a00), GATT_CHAR_PROP_BIT_READ);
2070 
2071     if (csis->start) {
2072       bool is_primary = true;
2073       bob.AddService(csis->start, csis->end, bluetooth::csis::kCsisServiceUuid, is_primary);
2074       if (csis->sirk_char) {
2075         bob.AddCharacteristic(csis->sirk_char, csis->sirk_char + 1, bluetooth::csis::kCsisSirkUuid,
2076                               GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
2077         if (csis->sirk_ccc) {
2078           bob.AddDescriptor(csis->sirk_ccc, Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
2079         }
2080       }
2081 
2082       if (csis->size_char) {
2083         bob.AddCharacteristic(csis->size_char, csis->size_char + 1, bluetooth::csis::kCsisSizeUuid,
2084                               GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
2085         if (csis->size_ccc) {
2086           bob.AddDescriptor(csis->size_ccc, Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
2087         }
2088       }
2089 
2090       if (csis->lock_char) {
2091         bob.AddCharacteristic(
2092                 csis->lock_char, csis->lock_char + 1, bluetooth::csis::kCsisLockUuid,
2093                 GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY | GATT_CHAR_PROP_BIT_WRITE);
2094         if (csis->lock_ccc) {
2095           bob.AddDescriptor(csis->lock_ccc, Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
2096         }
2097       }
2098 
2099       if (csis->rank_char) {
2100         bob.AddCharacteristic(csis->rank_char, csis->rank_char + 1, bluetooth::csis::kCsisRankUuid,
2101                               GATT_CHAR_PROP_BIT_READ);
2102       }
2103     }
2104 
2105     if (cas->start) {
2106       bool is_primary = true;
2107       bob.AddService(cas->start, cas->end, bluetooth::le_audio::uuid::kCapServiceUuid, is_primary);
2108       // Include CSIS service inside
2109       if (cas->csis_include) {
2110         bob.AddIncludedService(cas->csis_include, bluetooth::csis::kCsisServiceUuid, csis->start,
2111                                csis->end);
2112       }
2113     }
2114 
2115     if (pacs->start) {
2116       bool is_primary = true;
2117       bob.AddService(pacs->start, pacs->end,
2118                      bluetooth::le_audio::uuid::kPublishedAudioCapabilityServiceUuid, is_primary);
2119 
2120       if (pacs->sink_pac_char) {
2121         bob.AddCharacteristic(
2122                 pacs->sink_pac_char, pacs->sink_pac_char + 1,
2123                 bluetooth::le_audio::uuid::kSinkPublishedAudioCapabilityCharacteristicUuid,
2124                 GATT_CHAR_PROP_BIT_READ);
2125         if (pacs->sink_pac_ccc) {
2126           bob.AddDescriptor(pacs->sink_pac_ccc, Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
2127         }
2128       }
2129 
2130       if (pacs->sink_audio_loc_char) {
2131         bob.AddCharacteristic(pacs->sink_audio_loc_char, pacs->sink_audio_loc_char + 1,
2132                               bluetooth::le_audio::uuid::kSinkAudioLocationCharacteristicUuid,
2133                               GATT_CHAR_PROP_BIT_READ);
2134         if (pacs->sink_audio_loc_ccc) {
2135           bob.AddDescriptor(pacs->sink_audio_loc_ccc,
2136                             Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
2137         }
2138       }
2139 
2140       if (pacs->source_pac_char) {
2141         bob.AddCharacteristic(
2142                 pacs->source_pac_char, pacs->source_pac_char + 1,
2143                 bluetooth::le_audio::uuid::kSourcePublishedAudioCapabilityCharacteristicUuid,
2144                 GATT_CHAR_PROP_BIT_READ);
2145         if (pacs->source_pac_ccc) {
2146           bob.AddDescriptor(pacs->source_pac_ccc, Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
2147         }
2148       }
2149 
2150       if (pacs->source_audio_loc_char) {
2151         bob.AddCharacteristic(pacs->source_audio_loc_char, pacs->source_audio_loc_char + 1,
2152                               bluetooth::le_audio::uuid::kSourceAudioLocationCharacteristicUuid,
2153                               GATT_CHAR_PROP_BIT_READ);
2154         if (pacs->source_audio_loc_ccc) {
2155           bob.AddDescriptor(pacs->source_audio_loc_ccc,
2156                             Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
2157         }
2158       }
2159 
2160       if (pacs->avail_contexts_char) {
2161         bob.AddCharacteristic(
2162                 pacs->avail_contexts_char, pacs->avail_contexts_char + 1,
2163                 bluetooth::le_audio::uuid::kAudioContextAvailabilityCharacteristicUuid,
2164                 GATT_CHAR_PROP_BIT_READ);
2165         if (pacs->avail_contexts_ccc) {
2166           bob.AddDescriptor(pacs->avail_contexts_ccc,
2167                             Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
2168         }
2169       }
2170 
2171       if (pacs->supp_contexts_char) {
2172         bob.AddCharacteristic(pacs->supp_contexts_char, pacs->supp_contexts_char + 1,
2173                               bluetooth::le_audio::uuid::kAudioSupportedContextCharacteristicUuid,
2174                               GATT_CHAR_PROP_BIT_READ);
2175         if (pacs->supp_contexts_ccc) {
2176           bob.AddDescriptor(pacs->supp_contexts_ccc, Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
2177         }
2178       }
2179     }
2180 
2181     if (ascs->start) {
2182       bool is_primary = true;
2183       bob.AddService(ascs->start, ascs->end,
2184                      bluetooth::le_audio::uuid::kAudioStreamControlServiceUuid, is_primary);
2185       for (int i = 0; i < max_num_of_ases; i++) {
2186         if (ascs->sink_ase_char[i]) {
2187           bob.AddCharacteristic(ascs->sink_ase_char[i], ascs->sink_ase_char[i] + 1,
2188                                 bluetooth::le_audio::uuid::kSinkAudioStreamEndpointUuid,
2189                                 GATT_CHAR_PROP_BIT_READ);
2190           if (ascs->sink_ase_ccc[i]) {
2191             bob.AddDescriptor(ascs->sink_ase_ccc[i], Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
2192           }
2193         }
2194         if (ascs->source_ase_char[i]) {
2195           bob.AddCharacteristic(ascs->source_ase_char[i], ascs->source_ase_char[i] + 1,
2196                                 bluetooth::le_audio::uuid::kSourceAudioStreamEndpointUuid,
2197                                 GATT_CHAR_PROP_BIT_READ);
2198           if (ascs->source_ase_ccc[i]) {
2199             bob.AddDescriptor(ascs->source_ase_ccc[i],
2200                               Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
2201           }
2202         }
2203       }
2204       if (ascs->ctp_char) {
2205         bob.AddCharacteristic(
2206                 ascs->ctp_char, ascs->ctp_char + 1,
2207                 bluetooth::le_audio::uuid::kAudioStreamEndpointControlPointCharacteristicUuid,
2208                 GATT_CHAR_PROP_BIT_READ);
2209         if (ascs->ctp_ccc) {
2210           bob.AddDescriptor(ascs->ctp_ccc, Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
2211         }
2212       }
2213     }
2214 
2215     // Assign conn_id to a certain device - this does not mean it is connected
2216     auto dev_wrapper = std::make_unique<NiceMock<MockDeviceWrapper>>(
2217             addr, bob.Build().Services(), std::move(csis), std::move(cas), std::move(ascs),
2218             std::move(pacs));
2219     peer_devices.emplace(conn_id, std::move(dev_wrapper));
2220   }
2221 
SetSampleDatabaseEmpty(uint16_t conn_id,RawAddress addr)2222   void SetSampleDatabaseEmpty(uint16_t conn_id, RawAddress addr) {
2223     auto csis = std::make_unique<NiceMock<MockDeviceWrapper::csis_mock>>();
2224     auto cas = std::make_unique<NiceMock<MockDeviceWrapper::cas_mock>>();
2225     auto pacs = std::make_unique<NiceMock<MockDeviceWrapper::pacs_mock>>();
2226     auto ascs = std::make_unique<NiceMock<MockDeviceWrapper::ascs_mock>>();
2227     set_sample_database(conn_id, addr, std::move(csis), std::move(cas), std::move(ascs),
2228                         std::move(pacs));
2229   }
2230 
2231   struct SampleDatabaseParameters {
2232     uint16_t conn_id;
2233     RawAddress addr;
2234 
2235     std::optional<uint32_t> sink_audio_allocation = std::nullopt;
2236     std::optional<uint32_t> source_audio_allocation = std::nullopt;
2237     uint8_t sink_channel_cnt = 0x03;
2238     uint8_t source_channel_cnt = 0x03;
2239     uint16_t sample_freq_mask = 0x0004;
2240     bool add_csis = true;
2241     bool add_cas = true;
2242     bool add_pacs = true;
2243     int add_ascs_cnt = 1;
2244     uint8_t set_size = 2;
2245     uint8_t rank = 1;
2246     GattStatus gatt_status = GATT_SUCCESS;
2247     uint8_t max_supported_codec_frames_per_sdu = 1;
2248   };
2249 
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)2250   void SetSampleDatabaseEarbudsValid(
2251           uint16_t conn_id, RawAddress addr, uint32_t sink_audio_allocation,
2252           uint32_t source_audio_allocation, uint8_t sink_channel_cnt = 0x03,
2253           uint8_t source_channel_cnt = 0x03, uint16_t sample_freq_mask = 0x0004,
2254           bool add_csis = true, bool add_cas = true, bool add_pacs = true, int add_ascs_cnt = 1,
2255           uint8_t set_size = 2, uint8_t rank = 1, GattStatus gatt_status = GATT_SUCCESS) {
2256     SetSampleDatabaseEarbudsValid(SampleDatabaseParameters{
2257             .conn_id = conn_id,
2258             .addr = addr,
2259             .sink_audio_allocation = sink_audio_allocation,
2260             .source_audio_allocation = source_audio_allocation,
2261             .sink_channel_cnt = sink_channel_cnt,
2262             .source_channel_cnt = source_channel_cnt,
2263             .sample_freq_mask = sample_freq_mask,
2264             .add_csis = add_csis,
2265             .add_cas = add_cas,
2266             .add_pacs = add_pacs,
2267             .add_ascs_cnt = add_ascs_cnt,
2268             .set_size = set_size,
2269             .rank = rank,
2270             .gatt_status = gatt_status,
2271             .max_supported_codec_frames_per_sdu = 1,
2272     });
2273   }
2274 
SetSampleDatabaseEarbudsValid(const SampleDatabaseParameters & params)2275   void SetSampleDatabaseEarbudsValid(const SampleDatabaseParameters& params) {
2276     auto conn_id = params.conn_id;
2277     auto addr = params.addr;
2278     auto sink_audio_allocation = params.sink_audio_allocation;
2279     auto source_audio_allocation = params.source_audio_allocation;
2280     auto sink_channel_cnt = params.sink_channel_cnt;
2281     auto source_channel_cnt = params.source_channel_cnt;
2282     auto sample_freq_mask = params.sample_freq_mask;
2283     auto add_csis = params.add_csis;
2284     auto add_cas = params.add_cas;
2285     auto add_pacs = params.add_pacs;
2286     auto add_ascs_cnt = params.add_ascs_cnt;
2287     auto set_size = params.set_size;
2288     auto rank = params.rank;
2289     auto gatt_status = params.gatt_status;
2290     auto max_supported_codec_frames_per_sdu = params.max_supported_codec_frames_per_sdu;
2291 
2292     auto csis = std::make_unique<NiceMock<MockDeviceWrapper::csis_mock>>();
2293     if (add_csis) {
2294       // attribute handles
2295       csis->start = 0x0010;
2296       csis->sirk_char = 0x0020;
2297       csis->sirk_ccc = 0x0022;
2298       csis->size_char = 0x0023;
2299       csis->size_ccc = 0x0025;
2300       csis->lock_char = 0x0026;
2301       csis->lock_ccc = 0x0028;
2302       csis->rank_char = 0x0029;
2303       csis->end = 0x0030;
2304       // other params
2305       csis->size = set_size;
2306       csis->rank = rank;
2307     }
2308 
2309     auto cas = std::make_unique<NiceMock<MockDeviceWrapper::cas_mock>>();
2310     if (add_cas) {
2311       // attribute handles
2312       cas->start = 0x0040;
2313       if (add_csis) {
2314         cas->csis_include = 0x0041;
2315       }
2316       cas->end = 0x0050;
2317       // other params
2318     }
2319 
2320     auto pacs = std::make_unique<NiceMock<MockDeviceWrapper::pacs_mock>>();
2321     if (add_pacs) {
2322       // attribute handles
2323       pacs->start = 0x0060;
2324       if (sink_audio_allocation.has_value()) {
2325         pacs->sink_pac_char = 0x0061;
2326         pacs->sink_pac_ccc = 0x0063;
2327         pacs->sink_audio_loc_char = 0x0064;
2328         pacs->sink_audio_loc_ccc = 0x0066;
2329       }
2330       if (source_audio_allocation.has_value()) {
2331         pacs->source_pac_char = 0x0067;
2332         pacs->source_pac_ccc = 0x0069;
2333         pacs->source_audio_loc_char = 0x0070;
2334         pacs->source_audio_loc_ccc = 0x0072;
2335       }
2336       pacs->avail_contexts_char = 0x0073;
2337       pacs->avail_contexts_ccc = 0x0075;
2338       pacs->supp_contexts_char = 0x0076;
2339       pacs->supp_contexts_ccc = 0x0078;
2340       pacs->end = 0x0080;
2341       // other params
2342     }
2343 
2344     auto ascs = std::make_unique<NiceMock<MockDeviceWrapper::ascs_mock>>();
2345     if (add_ascs_cnt > 0) {
2346       // attribute handles
2347       ascs->start = 0x0090;
2348       uint16_t handle = 0x0091;
2349       for (int i = 0; i < add_ascs_cnt; i++) {
2350         if (sink_audio_allocation.has_value()) {
2351           ascs->sink_ase_char[i] = handle;
2352           handle += 2;
2353           ascs->sink_ase_ccc[i] = handle;
2354           handle++;
2355         }
2356 
2357         if (source_audio_allocation.has_value()) {
2358           ascs->source_ase_char[i] = handle;
2359           handle += 2;
2360           ascs->source_ase_ccc[i] = handle;
2361           handle++;
2362         }
2363       }
2364       ascs->ctp_char = handle;
2365       handle += 2;
2366       ascs->ctp_ccc = handle;
2367       handle++;
2368       ascs->end = handle;
2369       // other params
2370     }
2371 
2372     set_sample_database(conn_id, addr, std::move(csis), std::move(cas), std::move(ascs),
2373                         std::move(pacs));
2374 
2375     if (add_pacs) {
2376       uint8_t sample_freq[2];
2377       sample_freq[0] = (uint8_t)(sample_freq_mask);
2378       sample_freq[1] = (uint8_t)(sample_freq_mask >> 8);
2379 
2380       // Set pacs default read values
2381       ON_CALL(*peer_devices.at(conn_id)->pacs, OnGetCharacteristicValue(_))
2382               .WillByDefault([=, this](uint16_t handle) {
2383                 auto& pacs = peer_devices.at(conn_id)->pacs;
2384                 std::vector<uint8_t> value;
2385                 if (gatt_status == GATT_SUCCESS) {
2386                   if (handle == pacs->sink_pac_char + 1) {
2387                     if (empty_sink_pack_) {
2388                       value = {0x00};
2389                     } else {
2390                       value = {
2391                               // Num records
2392                               0x02,
2393                               // Codec_ID
2394                               0x06,
2395                               0x00,
2396                               0x00,
2397                               0x00,
2398                               0x00,
2399                               // Codec Spec. Caps. Len
2400                               0x10,
2401                               0x03, /* sample freq */
2402                               0x01,
2403                               sample_freq[0],
2404                               sample_freq[1],
2405                               0x02,
2406                               0x02, /* frame duration */
2407                               0x03,
2408                               0x02, /* channel count */
2409                               0x03,
2410                               sink_channel_cnt,
2411                               0x05,
2412                               0x04,
2413                               0x1E,
2414                               0x00,
2415                               0x78,
2416                               0x00,
2417                               // Metadata Length
2418                               0x00,
2419                               // Codec_ID
2420                               0x06,
2421                               0x00,
2422                               0x00,
2423                               0x00,
2424                               0x00,
2425                               // Codec Spec. Caps. Len
2426                               0x13,
2427                               0x03, /* sample freq */
2428                               0x01,
2429                               0x80, /* 48kHz */
2430                               0x00,
2431                               0x02, /* frame duration */
2432                               0x02,
2433                               0x03,
2434                               0x02, /* channel count */
2435                               0x03,
2436                               sink_channel_cnt,
2437                               0x05, /* octects per frame */
2438                               0x04,
2439                               0x78,
2440                               0x00,
2441                               0x78,
2442                               0x00,
2443                               0x02, /* Max supported codec frames per SDU */
2444                               0x05,
2445                               max_supported_codec_frames_per_sdu,
2446                               // Metadata Length
2447                               0x00,
2448                       };
2449                     }
2450                   } else if (handle == pacs->sink_audio_loc_char + 1) {
2451                     value = {
2452                             (uint8_t)(sink_audio_allocation.value_or(0)),
2453                             (uint8_t)(sink_audio_allocation.value_or(0) >> 8),
2454                             (uint8_t)(sink_audio_allocation.value_or(0) >> 16),
2455                             (uint8_t)(sink_audio_allocation.value_or(0) >> 24),
2456                     };
2457                   } else if (handle == pacs->source_pac_char + 1) {
2458                     if (empty_source_pack_) {
2459                       value = {0x00};
2460                     } else {
2461                       value = {
2462                               // Num records
2463                               0x02,
2464                               // Codec_ID
2465                               0x06,
2466                               0x00,
2467                               0x00,
2468                               0x00,
2469                               0x00,
2470                               // Codec Spec. Caps. Len
2471                               0x10,
2472                               0x03,
2473                               0x01,
2474                               sample_freq[0],
2475                               sample_freq[1],
2476                               0x02,
2477                               0x02,
2478                               0x03,
2479                               0x02,
2480                               0x03,
2481                               source_channel_cnt,
2482                               0x05,
2483                               0x04,
2484                               0x1E,
2485                               0x00,
2486                               0x78,
2487                               0x00,
2488                               // Metadata Length
2489                               0x00,
2490                               // Codec_ID
2491                               0x06,
2492                               0x00,
2493                               0x00,
2494                               0x00,
2495                               0x00,
2496                               // Codec Spec. Caps. Len
2497                               0x10,
2498                               0x03,
2499                               0x01,
2500                               0x24,
2501                               0x00,
2502                               0x02,
2503                               0x02,
2504                               0x03,
2505                               0x02,
2506                               0x03,
2507                               source_channel_cnt,
2508                               0x05,
2509                               0x04,
2510                               0x1E,
2511                               0x00,
2512                               0x50,
2513                               0x00,
2514                               // Metadata Length
2515                               0x00,
2516                       };
2517                     }
2518                   } else if (handle == pacs->source_audio_loc_char + 1) {
2519                     value = {
2520                             (uint8_t)(source_audio_allocation.value_or(0)),
2521                             (uint8_t)(source_audio_allocation.value_or(0) >> 8),
2522                             (uint8_t)(source_audio_allocation.value_or(0) >> 16),
2523                             (uint8_t)(source_audio_allocation.value_or(0) >> 24),
2524                     };
2525                   } else if (handle == pacs->avail_contexts_char + 1) {
2526                     value = {
2527                             // Sink Avail Contexts
2528                             (uint8_t)(available_snk_context_types_),
2529                             (uint8_t)(available_snk_context_types_ >> 8),
2530                             // Source Avail Contexts
2531                             (uint8_t)(available_src_context_types_),
2532                             (uint8_t)(available_src_context_types_ >> 8),
2533                     };
2534                   } else if (handle == pacs->supp_contexts_char + 1) {
2535                     value = {
2536                             // Sink Supp Contexts
2537                             (uint8_t)(supported_snk_context_types_),
2538                             (uint8_t)(supported_snk_context_types_ >> 8),
2539                             // Source Supp Contexts
2540                             (uint8_t)(supported_src_context_types_),
2541                             (uint8_t)(supported_src_context_types_ >> 8),
2542                     };
2543                   }
2544                 }
2545                 return std::make_pair(gatt_status, value);
2546               });
2547     }
2548 
2549     if (add_ascs_cnt > 0) {
2550       // Set ascs default read values
2551       ON_CALL(*peer_devices.at(conn_id)->ascs, OnGetCharacteristicValue(_))
2552               .WillByDefault([this, conn_id, gatt_status](uint16_t handle) {
2553                 auto& ascs = peer_devices.at(conn_id)->ascs;
2554                 std::vector<uint8_t> value;
2555                 bool is_ase_sink_request = false;
2556                 bool is_ase_src_request = false;
2557                 uint8_t idx;
2558 
2559                 if (handle == ascs->ctp_ccc && ccc_stored_byte_val_.has_value()) {
2560                   value = {*ccc_stored_byte_val_, 00};
2561                   return std::make_pair(gatt_read_ctp_ccc_status_, value);
2562                 }
2563 
2564                 if (gatt_status == GATT_SUCCESS) {
2565                   if (handle == ascs->ctp_ccc) {
2566                     value = UINT16_TO_VEC_UINT8(ascs->ctp_ccc_val);
2567                   } else {
2568                     for (idx = 0; idx < max_num_of_ases; idx++) {
2569                       if (handle == ascs->sink_ase_ccc[idx] + 1) {
2570                         value = UINT16_TO_VEC_UINT8(ascs->sink_ase_ccc_val[idx]);
2571                         break;
2572                       }
2573                       if (handle == ascs->source_ase_char[idx] + 1) {
2574                         value = UINT16_TO_VEC_UINT8(ascs->source_ase_ccc_val[idx]);
2575                         break;
2576                       }
2577                     }
2578                   }
2579 
2580                   for (idx = 0; idx < max_num_of_ases; idx++) {
2581                     if (handle == ascs->sink_ase_char[idx] + 1) {
2582                       is_ase_sink_request = true;
2583                       break;
2584                     }
2585                     if (handle == ascs->source_ase_char[idx] + 1) {
2586                       is_ase_src_request = true;
2587                       break;
2588                     }
2589                   }
2590 
2591                   if (is_ase_sink_request) {
2592                     value = {
2593                             // ASE ID
2594                             static_cast<uint8_t>(idx + 1),
2595                             // State
2596                             static_cast<uint8_t>(bluetooth::le_audio::types::AseState::
2597                                                          BTA_LE_AUDIO_ASE_STATE_IDLE),
2598                             // No Additional ASE params for IDLE state
2599                     };
2600                   } else if (is_ase_src_request) {
2601                     value = {
2602                             // ASE ID
2603                             static_cast<uint8_t>(idx + 6),
2604                             // State
2605                             static_cast<uint8_t>(bluetooth::le_audio::types::AseState::
2606                                                          BTA_LE_AUDIO_ASE_STATE_IDLE),
2607                             // No Additional ASE params for IDLE state
2608                     };
2609                   }
2610                 }
2611                 return std::make_pair(gatt_status, value);
2612               });
2613     }
2614   }
2615 
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)2616   void TestAudioDataTransfer(int group_id, uint8_t cis_count_out, uint8_t cis_count_in,
2617                              int data_len, int in_data_len = 40, uint16_t decoded_in_data_len = 0) {
2618     ASSERT_NE(unicast_source_hal_cb_, nullptr);
2619     ASSERT_NE(mock_le_audio_sink_hal_client_, nullptr);
2620 
2621     // Expect two channels ISO Data to be sent
2622     std::vector<uint16_t> handles;
2623     if (cis_count_out) {
2624       EXPECT_CALL(*mock_iso_manager_, SendIsoData(_, _, _))
2625               .Times(cis_count_out)
2626               .WillRepeatedly([&handles](uint16_t iso_handle, const uint8_t* /*data*/,
2627                                          uint16_t /*data_len*/) { handles.push_back(iso_handle); });
2628     }
2629     std::vector<uint8_t> data(data_len);
2630     unicast_source_hal_cb_->OnAudioDataReady(data);
2631 
2632     // Inject microphone data from group (2 CISes - pass stereo data in 1 call)
2633     if (decoded_in_data_len) {
2634       EXPECT_CALL(*mock_le_audio_sink_hal_client_, SendData(_, decoded_in_data_len))
2635               .Times(cis_count_in > 0 ? 1 : 0);
2636     } else {
2637       EXPECT_CALL(*mock_le_audio_sink_hal_client_, SendData(_, _)).Times(cis_count_in > 0 ? 1 : 0);
2638     }
2639     ASSERT_EQ(streaming_groups.count(group_id), 1u);
2640 
2641     if (cis_count_in) {
2642       ASSERT_NE(unicast_sink_hal_cb_, nullptr);
2643 
2644       ASSERT_NE(0lu, streaming_groups.count(group_id));
2645       auto group = streaming_groups.at(group_id);
2646       for (LeAudioDevice* device = group->GetFirstDevice(); device != nullptr;
2647            device = group->GetNextDevice(device)) {
2648         for (auto& ase : device->ases_) {
2649           if (ase.direction == bluetooth::le_audio::types::kLeAudioDirectionSource) {
2650             InjectIncomingIsoData(group_id, ase.cis_conn_hdl, in_data_len);
2651             --cis_count_in;
2652             if (!cis_count_in) {
2653               break;
2654             }
2655           }
2656         }
2657         if (!cis_count_in) {
2658           break;
2659         }
2660       }
2661     }
2662 
2663     SyncOnMainLoop();
2664     std::sort(handles.begin(), handles.end());
2665     ASSERT_EQ(cis_count_in, 0);
2666     handles.clear();
2667 
2668     Mock::VerifyAndClearExpectations(mock_iso_manager_);
2669     Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
2670   }
2671 
InjectIncomingIsoData(uint16_t cig_id,uint16_t cis_con_hdl,size_t payload_size)2672   void InjectIncomingIsoData(uint16_t cig_id, uint16_t cis_con_hdl, size_t payload_size) {
2673     BT_HDR* bt_hdr = (BT_HDR*)malloc(sizeof(BT_HDR) + payload_size);
2674 
2675     bt_hdr->offset = 0;
2676     bt_hdr->len = payload_size;
2677 
2678     bluetooth::hci::iso_manager::cis_data_evt cis_evt;
2679     cis_evt.cig_id = cig_id;
2680     cis_evt.cis_conn_hdl = cis_con_hdl;
2681     cis_evt.ts = 0;
2682     cis_evt.evt_lost = 0;
2683     cis_evt.p_msg = bt_hdr;
2684 
2685     ASSERT_NE(cig_callbacks_, nullptr);
2686     cig_callbacks_->OnCisEvent(bluetooth::hci::iso_manager::kIsoEventCisDataAvailable, &cis_evt);
2687     free(bt_hdr);
2688   }
2689 
InjectCisDisconnected(uint16_t cig_id,uint16_t cis_con_hdl,uint8_t reason=0)2690   void InjectCisDisconnected(uint16_t cig_id, uint16_t cis_con_hdl, uint8_t reason = 0) {
2691     bluetooth::hci::iso_manager::cis_disconnected_evt cis_evt;
2692     cis_evt.cig_id = cig_id;
2693     cis_evt.cis_conn_hdl = cis_con_hdl;
2694     cis_evt.reason = reason;
2695 
2696     ASSERT_NE(cig_callbacks_, nullptr);
2697     cig_callbacks_->OnCisEvent(bluetooth::hci::iso_manager::kIsoEventCisDisconnected, &cis_evt);
2698   }
2699 
InjectCigRemoved(uint8_t cig_id)2700   void InjectCigRemoved(uint8_t cig_id) {
2701     bluetooth::hci::iso_manager::cig_remove_cmpl_evt evt;
2702     evt.status = 0;
2703     evt.cig_id = cig_id;
2704 
2705     ASSERT_NE(cig_callbacks_, nullptr);
2706     cig_callbacks_->OnCisEvent(bluetooth::hci::iso_manager::kIsoEventCigOnRemoveCmpl, &evt);
2707   }
2708 
2709   NiceMock<MockAudioHalClientCallbacks> mock_audio_hal_client_callbacks_;
2710   LeAudioSourceAudioHalClient::Callbacks* unicast_source_hal_cb_ = nullptr;
2711   LeAudioSinkAudioHalClient::Callbacks* unicast_sink_hal_cb_ = nullptr;
2712 
2713   uint8_t default_channel_cnt = 0x03;
2714   uint8_t default_src_channel_cnt = default_channel_cnt;
2715   uint8_t default_ase_cnt = 1;
2716 
2717   NiceMock<MockCsisClient> mock_csis_client_module_;
2718   NiceMock<MockDeviceGroups> mock_groups_module_;
2719   bluetooth::groups::DeviceGroupsCallbacks* group_callbacks_;
2720   NiceMock<MockLeAudioGroupStateMachine> mock_state_machine_;
2721 
2722   NiceMock<MockFunction<void()>> mock_storage_load;
2723   NiceMock<MockFunction<bool()>> mock_hal_2_1_verifier;
2724 
2725   NiceMock<bluetooth::manager::MockBtmInterface> mock_btm_interface_;
2726   NiceMock<gatt::MockBtaGattInterface> mock_gatt_interface_;
2727   NiceMock<gatt::MockBtaGattQueue> mock_gatt_queue_;
2728   tBTA_GATTC_CBACK* gatt_callback;
2729   const uint8_t gatt_if = 0xfe;
2730   uint16_t global_conn_id = 1;
2731   bluetooth::le_audio::LeAudioGroupStateMachine::Callbacks* state_machine_callbacks_;
2732   std::map<int, LeAudioDeviceGroup*> streaming_groups;
2733   bool stay_at_qos_config_in_start_stream = false;
2734   bool stay_at_releasing_stop_stream = false;
2735 
2736   bool attach_to_stream_scheduled = false;
2737 
2738   bluetooth::hci::IsoManager* iso_manager_;
2739   MockIsoManager* mock_iso_manager_;
2740   bluetooth::hci::iso_manager::CigCallbacks* cig_callbacks_ = nullptr;
2741   uint16_t iso_con_counter_ = 1;
2742 
2743   bluetooth::le_audio::CodecManager* codec_manager_;
2744   MockCodecManager* mock_codec_manager_;
2745 
2746   uint16_t available_snk_context_types_ = 0xffff;
2747   uint16_t available_src_context_types_ = 0xffff;
2748   uint16_t supported_snk_context_types_ = 0xffff;
2749   uint16_t supported_src_context_types_ = 0xffff;
2750 
2751   bool empty_source_pack_;
2752   bool empty_sink_pack_;
2753 
2754   NiceMock<bluetooth::storage::MockBtifStorageInterface> mock_btif_storage_;
2755 
2756   std::map<uint16_t, std::unique_ptr<NiceMock<MockDeviceWrapper>>> peer_devices;
2757   std::list<int> group_locks;
2758   std::map<RawAddress, int> groups;
2759 
2760   /* CCC descriptor data */
2761   tGATT_STATUS gatt_read_ctp_ccc_status_ = GATT_SUCCESS;
2762   std::optional<uint8_t> ccc_stored_byte_val_ = std::nullopt;
2763 
2764   /* Audio track metadata */
2765   char* test_tags_ptr_ = nullptr;
2766 };
2767 
2768 class UnicastTest : public UnicastTestNoInit {
2769 protected:
SetUp()2770   void SetUp() override {
2771     UnicastTestNoInit::SetUp();
2772 
2773     EXPECT_CALL(mock_hal_2_1_verifier, Call()).Times(1);
2774     EXPECT_CALL(mock_storage_load, Call()).Times(1);
2775 
2776     ON_CALL(mock_btm_interface_, GetHCIConnHandle(_, _))
2777             .WillByDefault(
2778                     [this](RawAddress const& bd_addr, tBT_TRANSPORT /*transport*/) -> uint16_t {
2779                       for (auto const& [conn_id, dev_wrapper] : peer_devices) {
2780                         if (dev_wrapper->addr == bd_addr) {
2781                           return conn_id;
2782                         }
2783                       }
2784                       log::error("GetHCIConnHandle Mock: not a valid test device!");
2785                       return 0x00FE;
2786                     });
2787     ON_CALL(mock_btm_interface_, AclDisconnectFromHandle(_, _))
2788             .WillByDefault([this](uint16_t handle, tHCI_STATUS /*rs*/) {
2789               ASSERT_NE(handle, GATT_INVALID_CONN_ID);
2790               InjectDisconnectedEvent(handle, GATT_CONN_TERMINATE_LOCAL_HOST);
2791             });
2792 
2793     std::vector<::bluetooth::le_audio::btle_audio_codec_config_t> framework_encode_preference;
2794     BtaAppRegisterCallback app_register_callback;
2795     EXPECT_CALL(mock_gatt_interface_, AppRegister(_, _, _, _))
2796             .WillOnce(DoAll(SaveArg<1>(&gatt_callback), SaveArg<2>(&app_register_callback)));
2797     LeAudioClient::Initialize(
2798             &mock_audio_hal_client_callbacks_,
2799             base::Bind([](MockFunction<void()>* foo) { foo->Call(); }, &mock_storage_load),
2800             base::Bind([](MockFunction<bool()>* foo) { return foo->Call(); },
2801                        &mock_hal_2_1_verifier),
2802             framework_encode_preference);
2803 
2804     SyncOnMainLoop();
2805     ASSERT_TRUE(gatt_callback);
2806     ASSERT_TRUE(group_callbacks_);
2807     ASSERT_TRUE(app_register_callback);
2808     app_register_callback.Run(gatt_if, GATT_SUCCESS);
2809     Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
2810   }
2811 
TearDown()2812   void TearDown() override {
2813     MockCodecInterface::ClearMockInstanceHookList();
2814 
2815     // Clear the default actions before the parent class teardown is called
2816     Mock::VerifyAndClear(&mock_btm_interface_);
2817     Mock::VerifyAndClear(&mock_gatt_interface_);
2818     Mock::VerifyAndClear(&mock_audio_hal_client_callbacks_);
2819     groups.clear();
2820     UnicastTestNoInit::TearDown();
2821   }
2822 
TestSetupRemoteDevices(int group_id)2823   void TestSetupRemoteDevices(int group_id) {
2824     uint8_t group_size = 2;
2825 
2826     // Report working CSIS
2827     ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
2828 
2829     // First earbud
2830     const RawAddress test_address0 = GetTestAddress(0);
2831     EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
2832     ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
2833                       codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id,
2834                       1 /* rank*/);
2835 
2836     // Second earbud
2837     const RawAddress test_address1 = GetTestAddress(1);
2838     EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
2839     ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
2840                       codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id,
2841                       2 /* rank*/, true /*connect_through_csis*/);
2842 
2843     constexpr int gmcs_ccid = 1;
2844     constexpr int gtbs_ccid = 2;
2845     EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
2846     EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
2847     LeAudioClient::Get()->SetCcidInformation(gmcs_ccid,
2848                                              static_cast<int>(LeAudioContextType::MEDIA));
2849     LeAudioClient::Get()->SetCcidInformation(gtbs_ccid,
2850                                              static_cast<int>(LeAudioContextType::CONVERSATIONAL));
2851     LeAudioClient::Get()->GroupSetActive(group_id);
2852   }
2853 
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)2854   void TestSetCodecPreference(
2855           const btle_audio_codec_config_t* preferred_codec_config_before_streaming,
2856           const btle_audio_codec_config_t* preferred_codec_config_during_streaming,
2857           LeAudioContextType context_type, int group_id, bool set_before_streaming,
2858           bool set_while_streaming, bool is_using_set_before_streaming_codec_during_streaming,
2859           bool is_using_set_while_streaming_codec_during_streaming, bool is_reconfig) {
2860     auto config_before_streaming_str = preferred_codec_config_before_streaming
2861                                                ? preferred_codec_config_before_streaming->ToString()
2862                                                : "null";
2863     auto config_during_streaming_str = preferred_codec_config_during_streaming
2864                                                ? preferred_codec_config_during_streaming->ToString()
2865                                                : "null";
2866     log::debug(
2867             "preferred_codec_config_before_streaming: {}, "
2868             "preferred_codec_config_during_streaming: {}, context_type: {}, "
2869             "group_id: {}, set_before_streaming: {}, "
2870             "set_while_streaming: {}, "
2871             "is_using_set_before_streaming_codec_during_streaming: "
2872             "{},is_using_set_while_streaming_codec_during_streaming:{}, "
2873             "is_reconfig: {}",
2874             config_before_streaming_str, config_during_streaming_str,
2875             bluetooth::common::ToString(context_type), group_id, set_before_streaming,
2876             set_while_streaming, is_using_set_before_streaming_codec_during_streaming,
2877             is_using_set_while_streaming_codec_during_streaming, is_reconfig);
2878 
2879     if (context_type != LeAudioContextType::MEDIA &&
2880         context_type != LeAudioContextType::CONVERSATIONAL) {
2881       return;
2882     }
2883 
2884     if (set_before_streaming) {
2885       do_in_main_thread(base::BindOnce(&LeAudioClient::SetCodecConfigPreference,
2886                                        base::Unretained(LeAudioClient::Get()), group_id,
2887                                        *preferred_codec_config_before_streaming,
2888                                        *preferred_codec_config_before_streaming));
2889       SyncOnMainLoop();
2890     }
2891 
2892     types::BidirectionalPair<std::vector<uint8_t>> ccids;
2893     constexpr int gmcs_ccid = 1;
2894     constexpr int gtbs_ccid = 2;
2895     if (context_type == LeAudioContextType::MEDIA) {
2896       ccids = types::BidirectionalPair<std::vector<uint8_t>>{{gmcs_ccid}, {}};
2897       EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, ccids)).Times(1);
2898       StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
2899     } else {
2900       ccids = types::BidirectionalPair<std::vector<uint8_t>>{{gtbs_ccid}, {gtbs_ccid}};
2901       EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, ccids)).Times(1);
2902       StartStreaming(AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_CONTENT_TYPE_SPEECH, group_id);
2903     }
2904     Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
2905     Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
2906 
2907     ASSERT_EQ(LeAudioClient::Get()->IsUsingPreferredCodecConfig(group_id,
2908                                                                 static_cast<int>(context_type)),
2909               is_using_set_before_streaming_codec_during_streaming);
2910 
2911     uint8_t cis_count_out = 2;
2912     uint8_t cis_count_in = context_type == LeAudioContextType::MEDIA ? 0 : 2;
2913     TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
2914 
2915     if (set_while_streaming) {
2916       EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(is_reconfig);
2917       EXPECT_CALL(*mock_le_audio_source_hal_client_, ReconfigurationComplete()).Times(is_reconfig);
2918 
2919       do_in_main_thread(base::BindOnce(&LeAudioClient::SetCodecConfigPreference,
2920                                        base::Unretained(LeAudioClient::Get()), group_id,
2921                                        *preferred_codec_config_during_streaming,
2922                                        *preferred_codec_config_during_streaming));
2923       SyncOnMainLoop();
2924       ASSERT_EQ(LeAudioClient::Get()->IsUsingPreferredCodecConfig(group_id,
2925                                                                   static_cast<int>(context_type)),
2926                 is_using_set_while_streaming_codec_during_streaming);
2927 
2928       if (context_type == LeAudioContextType::MEDIA) {
2929         ccids = types::BidirectionalPair<std::vector<uint8_t>>{{gmcs_ccid}, {}};
2930         EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, ccids)).Times(1);
2931         StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
2932       } else {
2933         ccids = types::BidirectionalPair<std::vector<uint8_t>>{{gtbs_ccid}, {gtbs_ccid}};
2934         EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, ccids)).Times(1);
2935         StartStreaming(AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_CONTENT_TYPE_SPEECH, group_id);
2936       }
2937     }
2938 
2939     StopStreaming(group_id, context_type == LeAudioContextType::CONVERSATIONAL);
2940     Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
2941     Mock::VerifyAndClearExpectations(&mock_state_machine_);
2942   }
2943 };
2944 
2945 class UnicastTestHealthStatus : public UnicastTest {
2946 protected:
SetUp()2947   void SetUp() override {
2948     UnicastTest::SetUp();
2949     group_ = new LeAudioDeviceGroup(group_id_);
2950   }
2951 
TearDown()2952   void TearDown() override {
2953     delete group_;
2954     UnicastTest::TearDown();
2955   }
2956 
2957   const int group_id_ = 0;
2958   LeAudioDeviceGroup* group_ = nullptr;
2959 };
2960 
2961 class UnicastTestHandoverMode : public UnicastTest {
2962 protected:
SetUp()2963   void SetUp() override {
2964     use_handover_mode = true;
2965     UnicastTest::SetUp();
2966     group_ = new LeAudioDeviceGroup(group_id_);
2967   }
2968 
TearDown()2969   void TearDown() override {
2970     delete group_;
2971     UnicastTest::TearDown();
2972   }
2973 
2974   const int group_id_ = 0;
2975   LeAudioDeviceGroup* group_ = nullptr;
2976 };
2977 
TEST_F(UnicastTest,Initialize)2978 TEST_F(UnicastTest, Initialize) {
2979   ASSERT_NE(LeAudioClient::Get(), nullptr);
2980   ASSERT_TRUE(LeAudioClient::IsLeAudioClientRunning());
2981 }
2982 
TEST_F(UnicastTestNoInit,InitializeNoHal_2_1)2983 TEST_F(UnicastTestNoInit, InitializeNoHal_2_1) {
2984   ASSERT_FALSE(LeAudioClient::IsLeAudioClientRunning());
2985 
2986   // Report False when asked for Audio HAL 2.1 support
2987   ON_CALL(mock_hal_2_1_verifier, Call()).WillByDefault([]() -> bool { return false; });
2988 
2989   BtaAppRegisterCallback app_register_callback;
2990   ON_CALL(mock_gatt_interface_, AppRegister(_, _, _, _))
2991           .WillByDefault(DoAll(SaveArg<1>(&gatt_callback), SaveArg<2>(&app_register_callback)));
2992   std::vector<::bluetooth::le_audio::btle_audio_codec_config_t> framework_encode_preference;
2993 
2994   EXPECT_DEATH(
2995           LeAudioClient::Initialize(
2996                   &mock_audio_hal_client_callbacks_,
2997                   base::Bind([](MockFunction<void()>* foo) { foo->Call(); }, &mock_storage_load),
2998                   base::Bind([](MockFunction<bool()>* foo) { return foo->Call(); },
2999                              &mock_hal_2_1_verifier),
3000                   framework_encode_preference),
3001           "LE Audio Client requires Bluetooth Audio HAL V2.1 at least. Either "
3002           "disable LE Audio Profile, or update your HAL");
3003 }
3004 
TEST_F(UnicastTest,CleanupWhenUserConnecting)3005 TEST_F(UnicastTest, CleanupWhenUserConnecting) {
3006   const RawAddress test_address0 = GetTestAddress(0);
3007   uint16_t conn_id = 1;
3008   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3009                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
3010                                 default_src_channel_cnt, 0x0004,
3011                                 /* source sample freq 16khz */ true, /*add_csis*/
3012                                 true,                                /*add_cas*/
3013                                 true,                                /*add_pacs*/
3014                                 default_ase_cnt /*add_ascs*/);
3015 
3016   /* Remove default action on the direct connect */
3017   ON_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_DIRECT_CONNECTION, _)).WillByDefault(Return());
3018   ConnectLeAudio(test_address0, false, false);
3019 
3020   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, false)).Times(1);
3021   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, true)).Times(1);
3022   EXPECT_CALL(mock_btm_interface_, AclDisconnectFromHandle(conn_id, _)).Times(0);
3023   EXPECT_CALL(mock_gatt_interface_, Close(_)).Times(0);
3024 
3025   LeAudioClient::Cleanup();
3026   SyncOnMainLoop();
3027 
3028   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
3029 }
3030 
TEST_F(UnicastTest,CleanupWhenAutoConnecting)3031 TEST_F(UnicastTest, CleanupWhenAutoConnecting) {
3032   const RawAddress test_address0 = GetTestAddress(0);
3033   uint16_t conn_id = 1;
3034   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3035                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
3036                                 default_channel_cnt, 0x0004,
3037                                 /* source sample freq 16khz */ true, /*add_csis*/
3038                                 true,                                /*add_cas*/
3039                                 true,                                /*add_pacs*/
3040                                 default_ase_cnt /*add_ascs*/);
3041 
3042   log::info("Connect device");
3043   ConnectLeAudio(test_address0);
3044 
3045   /* Remove default action on the autoconnect */
3046   ON_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _))
3047           .WillByDefault(Return());
3048 
3049   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3050               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
3051           .Times(1);
3052   /* Make sure when remote device disconnects us, TA is used */
3053   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, _)).Times(1);
3054   EXPECT_CALL(mock_gatt_interface_,
3055               Open(gatt_if, test_address0, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _))
3056           .Times(1);
3057 
3058   InjectDisconnectedEvent(1, GATT_CONN_TERMINATE_PEER_USER);
3059   SyncOnMainLoop();
3060 
3061   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
3062 
3063   log::info("Device is in auto connect");
3064 
3065   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, false)).Times(1);
3066   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, true)).Times(0);
3067   EXPECT_CALL(mock_btm_interface_, AclDisconnectFromHandle(conn_id, _)).Times(0);
3068   EXPECT_CALL(mock_gatt_interface_, Close(_)).Times(0);
3069 
3070   LeAudioClient::Cleanup();
3071   SyncOnMainLoop();
3072 
3073   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
3074 }
3075 
TEST_F(UnicastTest,CleanupWhenConnected)3076 TEST_F(UnicastTest, CleanupWhenConnected) {
3077   const RawAddress test_address0 = GetTestAddress(0);
3078   uint16_t conn_id = 1;
3079   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3080                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
3081                                 default_channel_cnt, 0x0004,
3082                                 /* source sample freq 16khz */ true, /*add_csis*/
3083                                 true,                                /*add_cas*/
3084                                 true,                                /*add_pacs*/
3085                                 default_ase_cnt /*add_ascs*/);
3086 
3087   log::info("Connect device");
3088   ConnectLeAudio(test_address0);
3089 
3090   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, false)).Times(1);
3091   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, true)).Times(0);
3092   EXPECT_CALL(mock_btm_interface_, AclDisconnectFromHandle(conn_id, _)).Times(1);
3093   EXPECT_CALL(mock_gatt_interface_, Close(conn_id)).Times(1);
3094 
3095   LeAudioClient::Cleanup();
3096   SyncOnMainLoop();
3097 
3098   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
3099 }
3100 
TEST_F(UnicastTest,ConnectAndSetupPhy)3101 TEST_F(UnicastTest, ConnectAndSetupPhy) {
3102   const RawAddress test_address0 = GetTestAddress(0);
3103   uint16_t conn_id = 1;
3104   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3105                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
3106                                 default_channel_cnt, 0x0004,
3107                                 /* source sample freq 16khz */ true, /*add_csis*/
3108                                 true,                                /*add_cas*/
3109                                 true,                                /*add_pacs*/
3110                                 default_ase_cnt /*add_ascs*/);
3111 
3112   EXPECT_CALL(mock_btm_interface_, BleSetPhy(test_address0, PHY_LE_2M, PHY_LE_2M, 0)).Times(1);
3113   ConnectLeAudio(test_address0, false);
3114   Mock::VerifyAndClearExpectations(&mock_btm_interface_);
3115 
3116   EXPECT_CALL(mock_btm_interface_, BleSetPhy(test_address0, PHY_LE_2M, PHY_LE_2M, 0)).Times(1);
3117   InjectPhyChangedEvent(conn_id, 0, 0, GATT_REQ_NOT_SUPPORTED);
3118   SyncOnMainLoop();
3119   ON_CALL(mock_btm_interface_, BTM_IsEncrypted(test_address0, _))
3120           .WillByDefault(DoAll(Return(true)));
3121   InjectEncryptionChangedEvent(test_address0);
3122   SyncOnMainLoop();
3123   Mock::VerifyAndClearExpectations(&mock_btm_interface_);
3124 
3125   /* Make sure flag `acl_phy_update_done_` is cleared after disconnect.
3126    * Just repeat previous steps after reconnection
3127    */
3128   InjectDisconnectedEvent(conn_id);
3129   SyncOnMainLoop();
3130 
3131   EXPECT_CALL(mock_btm_interface_, BleSetPhy(test_address0, PHY_LE_2M, PHY_LE_2M, 0)).Times(1);
3132 
3133   ON_CALL(mock_btm_interface_, BTM_IsEncrypted(test_address0, _))
3134           .WillByDefault(DoAll(Return(false)));
3135   InjectConnectedEvent(test_address0, 1);
3136   SyncOnMainLoop();
3137   Mock::VerifyAndClearExpectations(&mock_btm_interface_);
3138 
3139   EXPECT_CALL(mock_btm_interface_, BleSetPhy(test_address0, PHY_LE_2M, PHY_LE_2M, 0)).Times(1);
3140   InjectPhyChangedEvent(conn_id, 0, 0, GATT_REQ_NOT_SUPPORTED);
3141   SyncOnMainLoop();
3142   ON_CALL(mock_btm_interface_, BTM_IsEncrypted(test_address0, _))
3143           .WillByDefault(DoAll(Return(true)));
3144   InjectEncryptionChangedEvent(test_address0);
3145   SyncOnMainLoop();
3146   Mock::VerifyAndClearExpectations(&mock_btm_interface_);
3147 }
3148 
TEST_F(UnicastTest,ConnectOneEarbudEmpty)3149 TEST_F(UnicastTest, ConnectOneEarbudEmpty) {
3150   const RawAddress test_address0 = GetTestAddress(0);
3151   SetSampleDatabaseEmpty(1, test_address0);
3152   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3153               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
3154           .Times(1);
3155   EXPECT_CALL(mock_gatt_interface_, Close(_)).Times(1);
3156   ConnectLeAudio(test_address0);
3157 }
3158 
TEST_F(UnicastTest,ConnectOneEarbudNoPacs)3159 TEST_F(UnicastTest, ConnectOneEarbudNoPacs) {
3160   const RawAddress test_address0 = GetTestAddress(0);
3161   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3162                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
3163                                 default_channel_cnt, 0x0004,
3164                                 /* source sample freq 16khz */ true, /*add_csis*/
3165                                 true,                                /*add_cas*/
3166                                 false,                               /*add_pacs*/
3167                                 default_ase_cnt /*add_ascs*/);
3168   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3169               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
3170           .Times(1);
3171   EXPECT_CALL(mock_gatt_interface_, Close(_)).Times(1);
3172   ConnectLeAudio(test_address0);
3173 }
3174 
TEST_F(UnicastTest,ConnectOneEarbudNoAscs)3175 TEST_F(UnicastTest, ConnectOneEarbudNoAscs) {
3176   const RawAddress test_address0 = GetTestAddress(0);
3177   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3178                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
3179                                 default_channel_cnt, 0x0004,
3180                                 /* source sample freq 16khz */ true, /*add_csis*/
3181                                 true,                                /*add_cas*/
3182                                 true,                                /*add_pacs*/
3183                                 0 /*add_ascs*/);
3184   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3185               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
3186           .Times(1);
3187   EXPECT_CALL(mock_gatt_interface_, Close(_)).Times(1);
3188   ConnectLeAudio(test_address0);
3189 }
3190 
TEST_F(UnicastTest,ConnectOneEarbudNoCas)3191 TEST_F(UnicastTest, ConnectOneEarbudNoCas) {
3192   const RawAddress test_address0 = GetTestAddress(0);
3193   uint16_t conn_id = 1;
3194   SetSampleDatabaseEarbudsValid(conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3195                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
3196                                 default_channel_cnt, 0x0004,
3197                                 /* source sample freq 16khz */ true, /*add_csis*/
3198                                 false,                               /*add_cas*/
3199                                 true,                                /*add_pacs*/
3200                                 default_ase_cnt /*add_ascs*/);
3201 
3202   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3203               OnConnectionState(ConnectionState::CONNECTED, test_address0))
3204           .Times(1);
3205   ConnectLeAudio(test_address0);
3206 }
3207 
TEST_F(UnicastTest,ConnectOneEarbudNoCsis)3208 TEST_F(UnicastTest, ConnectOneEarbudNoCsis) {
3209   const RawAddress test_address0 = GetTestAddress(0);
3210   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3211                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
3212                                 default_channel_cnt, 0x0004,
3213                                 /* source sample freq 16khz */ false, /*add_csis*/
3214                                 true,                                 /*add_cas*/
3215                                 true,                                 /*add_pacs*/
3216                                 default_ase_cnt /*add_ascs*/);
3217   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3218               OnConnectionState(ConnectionState::CONNECTED, test_address0))
3219           .Times(1);
3220   ConnectLeAudio(test_address0);
3221 }
3222 
TEST_F(UnicastTest,ConnectOneEarbudWithInvalidCsis)3223 TEST_F(UnicastTest, ConnectOneEarbudWithInvalidCsis) {
3224   const RawAddress test_address0 = GetTestAddress(0);
3225   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3226                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
3227                                 default_channel_cnt, 0x0004,
3228                                 /* source sample freq 16khz */ true, /*add_csis*/
3229                                 true,                                /*add_cas*/
3230                                 true,                                /*add_pacs*/
3231                                 default_ase_cnt /*add_ascs*/);
3232   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3233               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
3234           .Times(1);
3235   EXPECT_CALL(mock_gatt_interface_, Close(_)).Times(1);
3236 
3237   // Report working CSIS
3238   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
3239 
3240   /* Make sure Group has not knowledge about the device */
3241   ON_CALL(mock_groups_module_, GetGroupId(_, _))
3242           .WillByDefault([](const RawAddress& /*addr*/, bluetooth::Uuid /*uuid*/) {
3243             return bluetooth::groups::kGroupUnknown;
3244           });
3245 
3246   ConnectLeAudio(test_address0);
3247   SyncOnMainLoop();
3248   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
3249   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3250 }
3251 
TEST_F(UnicastTestHealthStatus,ConnectOneEarbudEmpty_withHealthStatus)3252 TEST_F(UnicastTestHealthStatus, ConnectOneEarbudEmpty_withHealthStatus) {
3253   const RawAddress test_address0 = GetTestAddress(0);
3254   SetSampleDatabaseEmpty(1, test_address0);
3255   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3256               OnHealthBasedRecommendationAction(test_address0, LeAudioHealthBasedAction::DISABLE))
3257           .Times(1);
3258   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3259               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
3260           .Times(1);
3261   EXPECT_CALL(mock_gatt_interface_, Close(_)).Times(1);
3262   ConnectLeAudio(test_address0);
3263   SyncOnMainLoop();
3264   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3265   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
3266 
3267   LeAudioHealthStatus::Get()->RemoveStatistics(test_address0, bluetooth::groups::kGroupUnknown);
3268 }
3269 
TEST_F(UnicastTestHealthStatus,ConnectOneEarbudNoPacs_withHealthStatus)3270 TEST_F(UnicastTestHealthStatus, ConnectOneEarbudNoPacs_withHealthStatus) {
3271   const RawAddress test_address0 = GetTestAddress(0);
3272   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3273                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
3274                                 default_channel_cnt, 0x0004,
3275                                 /* source sample freq 16khz */ true, /*add_csis*/
3276                                 true,                                /*add_cas*/
3277                                 false,                               /*add_pacs*/
3278                                 default_ase_cnt /*add_ascs*/);
3279   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3280               OnHealthBasedRecommendationAction(test_address0, LeAudioHealthBasedAction::DISABLE))
3281           .Times(1);
3282   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3283               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
3284           .Times(1);
3285   EXPECT_CALL(mock_gatt_interface_, Close(_)).Times(1);
3286   ConnectLeAudio(test_address0);
3287   SyncOnMainLoop();
3288   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3289   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
3290 
3291   LeAudioHealthStatus::Get()->RemoveStatistics(test_address0, bluetooth::groups::kGroupUnknown);
3292 }
3293 
TEST_F(UnicastTestHealthStatus,ConnectOneEarbudNoAscs_withHealthStatus)3294 TEST_F(UnicastTestHealthStatus, ConnectOneEarbudNoAscs_withHealthStatus) {
3295   const RawAddress test_address0 = GetTestAddress(0);
3296   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3297                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
3298                                 default_channel_cnt, 0x0004,
3299                                 /* source sample freq 16khz */ true, /*add_csis*/
3300                                 true,                                /*add_cas*/
3301                                 true,                                /*add_pacs*/
3302                                 0 /*add_ascs*/);
3303   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3304               OnHealthBasedRecommendationAction(test_address0, LeAudioHealthBasedAction::DISABLE))
3305           .Times(1);
3306   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3307               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
3308           .Times(1);
3309   EXPECT_CALL(mock_gatt_interface_, Close(_)).Times(1);
3310   ConnectLeAudio(test_address0);
3311   SyncOnMainLoop();
3312   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3313   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
3314 
3315   LeAudioHealthStatus::Get()->RemoveStatistics(test_address0, bluetooth::groups::kGroupUnknown);
3316 }
3317 
TEST_F(UnicastTestHealthStatus,ConnectOneEarbudNoCas_withHealthStatus)3318 TEST_F(UnicastTestHealthStatus, ConnectOneEarbudNoCas_withHealthStatus) {
3319   const RawAddress test_address0 = GetTestAddress(0);
3320   uint16_t conn_id = 1;
3321   SetSampleDatabaseEarbudsValid(conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3322                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
3323                                 default_channel_cnt, 0x0004,
3324                                 /* source sample freq 16khz */ true, /*add_csis*/
3325                                 false,                               /*add_cas*/
3326                                 true,                                /*add_pacs*/
3327                                 default_ase_cnt /*add_ascs*/);
3328 
3329   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3330               OnHealthBasedRecommendationAction(test_address0, LeAudioHealthBasedAction::DISABLE))
3331           .Times(0);
3332   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3333               OnConnectionState(ConnectionState::CONNECTED, test_address0))
3334           .Times(1);
3335   ConnectLeAudio(test_address0);
3336   SyncOnMainLoop();
3337   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3338 
3339   LeAudioHealthStatus::Get()->RemoveStatistics(test_address0, bluetooth::groups::kGroupUnknown);
3340 }
3341 
TEST_F(UnicastTestHealthStatus,ConnectOneEarbudNoCsis_withHealthStatus)3342 TEST_F(UnicastTestHealthStatus, ConnectOneEarbudNoCsis_withHealthStatus) {
3343   const RawAddress test_address0 = GetTestAddress(0);
3344   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3345                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
3346                                 default_channel_cnt, 0x0004,
3347                                 /* source sample freq 16khz */ false, /*add_csis*/
3348                                 true,                                 /*add_cas*/
3349                                 true,                                 /*add_pacs*/
3350                                 default_ase_cnt /*add_ascs*/);
3351   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3352               OnHealthBasedRecommendationAction(test_address0, LeAudioHealthBasedAction::DISABLE))
3353           .Times(0);
3354   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3355               OnConnectionState(ConnectionState::CONNECTED, test_address0))
3356           .Times(1);
3357   ConnectLeAudio(test_address0);
3358   SyncOnMainLoop();
3359   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3360 
3361   LeAudioHealthStatus::Get()->RemoveStatistics(test_address0, bluetooth::groups::kGroupUnknown);
3362 }
3363 
TEST_F(UnicastTestHealthStatus,ConnectOneEarbudWithInvalidCsis_withHealthStatus)3364 TEST_F(UnicastTestHealthStatus, ConnectOneEarbudWithInvalidCsis_withHealthStatus) {
3365   const RawAddress test_address0 = GetTestAddress(0);
3366   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3367                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
3368                                 default_channel_cnt, 0x0004,
3369                                 /* source sample freq 16khz */ true, /*add_csis*/
3370                                 true,                                /*add_cas*/
3371                                 true,                                /*add_pacs*/
3372                                 default_ase_cnt /*add_ascs*/);
3373   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3374               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
3375           .Times(1);
3376   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3377               OnHealthBasedRecommendationAction(test_address0, LeAudioHealthBasedAction::DISABLE))
3378           .Times(1);
3379 
3380   EXPECT_CALL(mock_gatt_interface_, Close(_)).Times(1);
3381 
3382   // Report working CSIS
3383   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
3384 
3385   /* Make sure Group has not knowledge about the device */
3386   ON_CALL(mock_groups_module_, GetGroupId(_, _))
3387           .WillByDefault([](const RawAddress& /*addr*/, bluetooth::Uuid /*uuid*/) {
3388             return bluetooth::groups::kGroupUnknown;
3389           });
3390 
3391   ConnectLeAudio(test_address0);
3392   SyncOnMainLoop();
3393   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
3394   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3395 
3396   LeAudioHealthStatus::Get()->RemoveStatistics(test_address0, bluetooth::groups::kGroupUnknown);
3397 }
3398 
TEST_F(UnicastTestHealthStatus,ConnectOneEarbudDisable_withHealthStatus)3399 TEST_F(UnicastTestHealthStatus, ConnectOneEarbudDisable_withHealthStatus) {
3400   const RawAddress test_address0 = GetTestAddress(0);
3401   int conn_id = 1;
3402 
3403   SetSampleDatabaseEarbudsValid(conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3404                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
3405                                 default_channel_cnt, 0x0004, false);
3406   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3407               OnConnectionState(ConnectionState::CONNECTED, test_address0))
3408           .Times(1);
3409 
3410   ConnectLeAudio(test_address0);
3411   SyncOnMainLoop();
3412   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3413 
3414   LeAudioClient::Get()->GroupSetActive(group_id_);
3415   auto device = std::make_shared<LeAudioDevice>(test_address0, DeviceConnectState::DISCONNECTED);
3416   group_->AddNode(device);
3417   SyncOnMainLoop();
3418 
3419   auto health_status = LeAudioHealthStatus::Get();
3420 
3421   /* Inject stream error */
3422   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3423               OnHealthBasedGroupRecommendationAction(group_id_, LeAudioHealthBasedAction::DISABLE))
3424           .Times(1);
3425   health_status->AddStatisticForGroup(group_, LeAudioHealthGroupStatType::STREAM_CREATE_CIS_FAILED);
3426   health_status->AddStatisticForGroup(group_, LeAudioHealthGroupStatType::STREAM_CREATE_CIS_FAILED);
3427 
3428   /* Do not act on disconnect */
3429   ON_CALL(mock_gatt_interface_, Close(_)).WillByDefault(DoAll(Return()));
3430   ON_CALL(mock_btm_interface_, AclDisconnectFromHandle(_, _)).WillByDefault(DoAll(Return()));
3431 
3432   state_machine_callbacks_->OnStateTransitionTimeout(group_id_);
3433   SyncOnMainLoop();
3434   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3435 
3436   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3437               OnHealthBasedGroupRecommendationAction(group_id_, LeAudioHealthBasedAction::DISABLE))
3438           .Times(0);
3439   health_status->AddStatisticForGroup(group_, LeAudioHealthGroupStatType::STREAM_CREATE_CIS_FAILED);
3440   health_status->AddStatisticForGroup(group_, LeAudioHealthGroupStatType::STREAM_CREATE_CIS_FAILED);
3441   SyncOnMainLoop();
3442   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3443 }
3444 
TEST_F(UnicastTestHealthStatus,ConnectOneEarbudConsiderDisabling_withHealthStatus)3445 TEST_F(UnicastTestHealthStatus, ConnectOneEarbudConsiderDisabling_withHealthStatus) {
3446   const RawAddress test_address0 = GetTestAddress(0);
3447   int conn_id = 1;
3448 
3449   SetSampleDatabaseEarbudsValid(conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3450                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
3451                                 default_channel_cnt, 0x0004, false);
3452   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3453               OnConnectionState(ConnectionState::CONNECTED, test_address0))
3454           .Times(1);
3455 
3456   ConnectLeAudio(test_address0);
3457   SyncOnMainLoop();
3458   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3459 
3460   LeAudioClient::Get()->GroupSetActive(group_id_);
3461   auto device = std::make_shared<LeAudioDevice>(test_address0, DeviceConnectState::DISCONNECTED);
3462   group_->AddNode(device);
3463   SyncOnMainLoop();
3464 
3465   auto health_status = LeAudioHealthStatus::Get();
3466 
3467   /* Inject stream success and error */
3468   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3469               OnHealthBasedGroupRecommendationAction(group_id_,
3470                                                      LeAudioHealthBasedAction::CONSIDER_DISABLING))
3471           .Times(1);
3472   health_status->AddStatisticForGroup(group_, LeAudioHealthGroupStatType::STREAM_CREATE_SUCCESS);
3473   health_status->AddStatisticForGroup(group_, LeAudioHealthGroupStatType::STREAM_CREATE_CIS_FAILED);
3474   health_status->AddStatisticForGroup(group_, LeAudioHealthGroupStatType::STREAM_CREATE_CIS_FAILED);
3475 
3476   /* Do not act on disconnect */
3477   ON_CALL(mock_gatt_interface_, Close(_)).WillByDefault(DoAll(Return()));
3478   ON_CALL(mock_btm_interface_, AclDisconnectFromHandle(_, _)).WillByDefault(DoAll(Return()));
3479 
3480   state_machine_callbacks_->OnStateTransitionTimeout(group_id_);
3481   SyncOnMainLoop();
3482   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3483 
3484   EXPECT_CALL(
3485           mock_audio_hal_client_callbacks_,
3486           OnHealthBasedGroupRecommendationAction(1, LeAudioHealthBasedAction::CONSIDER_DISABLING))
3487           .Times(0);
3488   health_status->AddStatisticForGroup(group_, LeAudioHealthGroupStatType::STREAM_CREATE_CIS_FAILED);
3489   health_status->AddStatisticForGroup(group_, LeAudioHealthGroupStatType::STREAM_CREATE_CIS_FAILED);
3490   SyncOnMainLoop();
3491   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3492 }
3493 
TEST_F(UnicastTest,ConnectDisconnectOneEarbud)3494 TEST_F(UnicastTest, ConnectDisconnectOneEarbud) {
3495   const RawAddress test_address0 = GetTestAddress(0);
3496   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3497                                 codec_spec_conf::kLeAudioLocationStereo);
3498   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3499               OnConnectionState(ConnectionState::CONNECTED, test_address0))
3500           .Times(1);
3501   ConnectLeAudio(test_address0);
3502   DisconnectLeAudioWithAclClose(test_address0, 1);
3503 }
3504 
TEST_F(UnicastTest,ConnectRemoteServiceDiscoveryCompleteBeforeEncryption)3505 TEST_F(UnicastTest, ConnectRemoteServiceDiscoveryCompleteBeforeEncryption) {
3506   const RawAddress test_address0 = GetTestAddress(0);
3507   uint16_t conn_id = 1;
3508   SetSampleDatabaseEarbudsValid(conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3509                                 codec_spec_conf::kLeAudioLocationStereo);
3510   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3511               OnConnectionState(ConnectionState::CONNECTED, test_address0))
3512           .Times(0);
3513   ConnectLeAudio(test_address0, false);
3514   InjectSearchCompleteEvent(conn_id);
3515 
3516   SyncOnMainLoop();
3517   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3518 
3519   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3520               OnConnectionState(ConnectionState::CONNECTED, test_address0))
3521           .Times(1);
3522   ON_CALL(mock_btm_interface_, BTM_IsEncrypted(test_address0, _))
3523           .WillByDefault(DoAll(Return(true)));
3524   InjectEncryptionChangedEvent(test_address0);
3525   SyncOnMainLoop();
3526   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3527 }
3528 
TEST_F(UnicastTest,DisconnectWhenLinkKeyIsGone)3529 TEST_F(UnicastTest, DisconnectWhenLinkKeyIsGone) {
3530   const RawAddress test_address0 = GetTestAddress(0);
3531   uint16_t conn_id = 1;
3532   SetSampleDatabaseEarbudsValid(conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3533                                 codec_spec_conf::kLeAudioLocationStereo);
3534   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3535               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
3536           .Times(1);
3537 
3538   ON_CALL(mock_btm_interface_, BTM_IsEncrypted(test_address0, _))
3539           .WillByDefault(DoAll(Return(false)));
3540 
3541   ON_CALL(mock_btm_interface_, SetEncryption(test_address0, _, _, _, _))
3542           .WillByDefault(Return(tBTM_STATUS::BTM_ERR_KEY_MISSING));
3543 
3544   EXPECT_CALL(mock_gatt_interface_, Close(conn_id)).Times(1);
3545   do_in_main_thread(base::BindOnce(&LeAudioClient::Connect, base::Unretained(LeAudioClient::Get()),
3546                                    test_address0));
3547 
3548   SyncOnMainLoop();
3549   Mock::VerifyAndClearExpectations(&mock_btm_interface_);
3550   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
3551 }
3552 
3553 /* same as above case except the disconnect is initiated by remote */
TEST_F(UnicastTest,ConnectRemoteDisconnectOneEarbud)3554 TEST_F(UnicastTest, ConnectRemoteDisconnectOneEarbud) {
3555   const RawAddress test_address0 = GetTestAddress(0);
3556   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3557                                 codec_spec_conf::kLeAudioLocationStereo);
3558   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3559               OnConnectionState(ConnectionState::CONNECTED, test_address0))
3560           .Times(1);
3561   ConnectLeAudio(test_address0);
3562   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
3563 
3564   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3565               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
3566           .Times(1);
3567   /* Make sure when remote device disconnects us, TA is used */
3568   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, _)).Times(1);
3569   EXPECT_CALL(mock_gatt_interface_,
3570               Open(gatt_if, test_address0, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _))
3571           .Times(1);
3572 
3573   InjectDisconnectedEvent(1, GATT_CONN_TERMINATE_PEER_USER);
3574   SyncOnMainLoop();
3575 
3576   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
3577 
3578   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3579               OnConnectionState(ConnectionState::CONNECTED, test_address0))
3580           .Times(1);
3581 
3582   /* When reconnected, we always remove background connect, as we do not track
3583    * which type (allow list or TA) was used and then make sure the TA is used.
3584    */
3585   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, _)).Times(1);
3586   EXPECT_CALL(mock_gatt_interface_,
3587               Open(gatt_if, test_address0, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _))
3588           .Times(1);
3589 
3590   /* For background connect, test needs to Inject Connected Event */
3591   InjectConnectedEvent(test_address0, 1);
3592   SyncOnMainLoop();
3593   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
3594 }
3595 
3596 /* same as above case except the disconnect is initiated by remote */
TEST_F(UnicastTest,ConnectRemoteDisconnectOnTimeoutOneEarbud)3597 TEST_F(UnicastTest, ConnectRemoteDisconnectOnTimeoutOneEarbud) {
3598   const RawAddress test_address0 = GetTestAddress(0);
3599   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3600                                 codec_spec_conf::kLeAudioLocationStereo);
3601   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3602               OnConnectionState(ConnectionState::CONNECTED, test_address0))
3603           .Times(1);
3604   ConnectLeAudio(test_address0);
3605   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3606               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
3607           .Times(1);
3608 
3609   /* Remove default action on the direct connect */
3610   ON_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_DIRECT_CONNECTION, _)).WillByDefault(Return());
3611 
3612   /* For remote disconnection, expect stack to try background re-connect */
3613   EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address0, BTM_BLE_DIRECT_CONNECTION, _))
3614           .Times(1);
3615 
3616   InjectDisconnectedEvent(1, GATT_CONN_TIMEOUT);
3617   SyncOnMainLoop();
3618 
3619   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
3620 
3621   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3622               OnConnectionState(ConnectionState::CONNECTED, test_address0))
3623           .Times(1);
3624 
3625   /* For background connect, test needs to Inject Connected Event */
3626   InjectConnectedEvent(test_address0, 1);
3627   SyncOnMainLoop();
3628 }
3629 
TEST_F(UnicastTest,ConnectTwoEarbudsCsisGrouped)3630 TEST_F(UnicastTest, ConnectTwoEarbudsCsisGrouped) {
3631   uint8_t group_size = 2;
3632   int group_id = 2;
3633 
3634   // Report working CSIS
3635   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
3636 
3637   // First earbud
3638   const RawAddress test_address0 = GetTestAddress(0);
3639   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
3640   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
3641                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
3642 
3643   // Second earbud
3644   const RawAddress test_address1 = GetTestAddress(1);
3645   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
3646   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
3647                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
3648                     true /*connect_through_csis*/);
3649 
3650   Mock::VerifyAndClearExpectations(&mock_btif_storage_);
3651 
3652   /* for Target announcements AutoConnect is always there, until
3653    * device is removed
3654    */
3655   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, false)).Times(0);
3656   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, false)).Times(0);
3657 
3658   // Verify grouping information
3659   std::vector<RawAddress> devs = LeAudioClient::Get()->GetGroupDevices(group_id);
3660   ASSERT_NE(std::find(devs.begin(), devs.end(), test_address0), devs.end());
3661   ASSERT_NE(std::find(devs.begin(), devs.end(), test_address1), devs.end());
3662 
3663   DisconnectLeAudioWithAclClose(test_address0, 1);
3664   DisconnectLeAudioWithAclClose(test_address1, 2);
3665 }
3666 
TEST_F(UnicastTest,ConnectTwoEarbudsCsisGroupUnknownAtConnect)3667 TEST_F(UnicastTest, ConnectTwoEarbudsCsisGroupUnknownAtConnect) {
3668   uint8_t group_size = 2;
3669   uint8_t group_id = 2;
3670 
3671   // Report working CSIS
3672   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
3673 
3674   // First earbud connects without known grouping
3675   const RawAddress test_address0 = GetTestAddress(0);
3676   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
3677   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
3678                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
3679 
3680   // Second earbud
3681   const RawAddress test_address1 = GetTestAddress(1);
3682   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
3683   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
3684                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
3685                     true /*connect_through_csis*/);
3686 
3687   Mock::VerifyAndClearExpectations(&mock_btif_storage_);
3688 
3689   // Verify grouping information
3690   std::vector<RawAddress> devs = LeAudioClient::Get()->GetGroupDevices(group_id);
3691   ASSERT_NE(std::find(devs.begin(), devs.end(), test_address0), devs.end());
3692   ASSERT_NE(std::find(devs.begin(), devs.end(), test_address1), devs.end());
3693 
3694   /* for Target announcements AutoConnect is always there, until
3695    *  device is removed
3696    */
3697   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, false)).Times(0);
3698   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, false)).Times(0);
3699   DisconnectLeAudioWithAclClose(test_address0, 1);
3700   DisconnectLeAudioWithAclClose(test_address1, 2);
3701 }
3702 
TEST_F(UnicastTestNoInit,ConnectFailedDueToInvalidParameters)3703 TEST_F(UnicastTestNoInit, ConnectFailedDueToInvalidParameters) {
3704   // Prepare two devices
3705   uint8_t group_size = 2;
3706   uint8_t group_id = 2;
3707 
3708   /* Prepare  mock to not inject connect event so the device can stay in
3709    * CONNECTING state*/
3710   ON_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_DIRECT_CONNECTION, false))
3711           .WillByDefault(DoAll(Return()));
3712 
3713   const RawAddress test_address0 = GetTestAddress(0);
3714   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationFrontLeft,
3715                                 codec_spec_conf::kLeAudioLocationFrontLeft, default_channel_cnt,
3716                                 default_channel_cnt, 0x0004,
3717                                 /* source sample freq 16khz */ true, /*add_csis*/
3718                                 true,                                /*add_cas*/
3719                                 true,                                /*add_pacs*/
3720                                 default_ase_cnt,                     /*add_ascs_cnt*/
3721                                 group_size, 1);
3722 
3723   const RawAddress test_address1 = GetTestAddress(1);
3724   SetSampleDatabaseEarbudsValid(2, test_address1, codec_spec_conf::kLeAudioLocationFrontRight,
3725                                 codec_spec_conf::kLeAudioLocationFrontRight, default_channel_cnt,
3726                                 default_channel_cnt, 0x0004,
3727                                 /* source sample freq 16khz */ true, /*add_csis*/
3728                                 true,                                /*add_cas*/
3729                                 true,                                /*add_pacs*/
3730                                 default_ase_cnt,                     /*add_ascs_cnt*/
3731                                 group_size, 2);
3732 
3733   // Load devices from the storage when storage API is called
3734   bool autoconnect = true;
3735 
3736   /* Common storage values */
3737   std::vector<uint8_t> handles;
3738   LeAudioClient::GetHandlesForStorage(test_address0, handles);
3739 
3740   std::vector<uint8_t> ases;
3741   LeAudioClient::GetAsesForStorage(test_address0, ases);
3742 
3743   std::vector<uint8_t> src_pacs;
3744   LeAudioClient::GetSourcePacsForStorage(test_address0, src_pacs);
3745 
3746   std::vector<uint8_t> snk_pacs;
3747   LeAudioClient::GetSinkPacsForStorage(test_address0, snk_pacs);
3748 
3749   std::vector<uint8_t> gmap_data;
3750   LeAudioClient::GetGmapForStorage(test_address0, gmap_data);
3751 
3752   EXPECT_CALL(mock_storage_load, Call()).WillOnce([&]() {
3753     do_in_main_thread(base::Bind(&LeAudioClient::AddFromStorage, test_address0, autoconnect,
3754                                  codec_spec_conf::kLeAudioLocationFrontLeft,
3755                                  codec_spec_conf::kLeAudioLocationFrontLeft, 0xff, 0xff,
3756                                  std::move(handles), std::move(snk_pacs), std::move(src_pacs),
3757                                  std::move(ases), std::move(gmap_data)));
3758     do_in_main_thread(base::Bind(&LeAudioClient::AddFromStorage, test_address1, autoconnect,
3759                                  codec_spec_conf::kLeAudioLocationFrontRight,
3760                                  codec_spec_conf::kLeAudioLocationFrontRight, 0xff, 0xff,
3761                                  std::move(handles), std::move(snk_pacs), std::move(src_pacs),
3762                                  std::move(ases), std::move(gmap_data)));
3763   });
3764 
3765   // Expect stored device0 to connect automatically (first directed connection )
3766   EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address0, BTM_BLE_DIRECT_CONNECTION, _))
3767           .Times(1);
3768 
3769   // Expect stored device1 to connect automatically (first direct connection)
3770   EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address1, BTM_BLE_DIRECT_CONNECTION, _))
3771           .Times(1);
3772 
3773   ON_CALL(mock_btm_interface_, BTM_IsEncrypted(test_address1, _))
3774           .WillByDefault(DoAll(Return(true)));
3775   ON_CALL(mock_btm_interface_, BTM_IsEncrypted(test_address0, _))
3776           .WillByDefault(DoAll(Return(true)));
3777 
3778   ON_CALL(mock_groups_module_, GetGroupId(_, _)).WillByDefault(DoAll(Return(group_id)));
3779 
3780   ON_CALL(mock_btm_interface_, GetSecurityFlagsByTransport(test_address0, NotNull(), _))
3781           .WillByDefault(DoAll(SetArgPointee<1>(BTM_SEC_FLAG_ENCRYPTED), Return(true)));
3782 
3783   std::vector<::bluetooth::le_audio::btle_audio_codec_config_t> framework_encode_preference;
3784 
3785   // Initialize
3786   BtaAppRegisterCallback app_register_callback;
3787   ON_CALL(mock_gatt_interface_, AppRegister(_, _, _, _))
3788           .WillByDefault(DoAll(SaveArg<1>(&gatt_callback), SaveArg<2>(&app_register_callback)));
3789   LeAudioClient::Initialize(
3790           &mock_audio_hal_client_callbacks_,
3791           base::Bind([](MockFunction<void()>* foo) { foo->Call(); }, &mock_storage_load),
3792           base::Bind([](MockFunction<bool()>* foo) { return foo->Call(); }, &mock_hal_2_1_verifier),
3793           framework_encode_preference);
3794   if (app_register_callback) {
3795     app_register_callback.Run(gatt_if, GATT_SUCCESS);
3796   }
3797 
3798   // We need to wait for the storage callback before verifying stuff
3799   SyncOnMainLoop();
3800   ASSERT_TRUE(LeAudioClient::IsLeAudioClientRunning());
3801   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
3802 
3803   // Simulate connect parameters are invalid and phone does not fallback
3804   // to background connect.
3805   EXPECT_CALL(mock_gatt_interface_,
3806               Open(gatt_if, test_address0, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _))
3807           .Times(0);
3808 
3809   EXPECT_CALL(mock_gatt_interface_,
3810               Open(gatt_if, test_address1, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _))
3811           .Times(0);
3812 
3813   // Devices not found
3814   InjectConnectedEvent(test_address0, 0, GATT_ILLEGAL_PARAMETER);
3815   InjectConnectedEvent(test_address1, 0, GATT_ILLEGAL_PARAMETER);
3816 
3817   SyncOnMainLoop();
3818   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
3819 }
3820 
TEST_F(UnicastTestNoInit,LoadStoredEarbudsBroakenStorage)3821 TEST_F(UnicastTestNoInit, LoadStoredEarbudsBroakenStorage) {
3822   // Prepare two devices
3823   uint8_t group_size = 2;
3824   uint8_t group_id = 2;
3825   /* If the storage has been broken, make sure device will be rediscovered after
3826    * reconnection
3827    */
3828 
3829   /* Prepare  mock to not inject connect event so the device can stay in
3830    * CONNECTING state*/
3831   ON_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_DIRECT_CONNECTION, false))
3832           .WillByDefault(DoAll(Return()));
3833 
3834   const RawAddress test_address0 = GetTestAddress(0);
3835   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationFrontLeft,
3836                                 codec_spec_conf::kLeAudioLocationFrontLeft, default_channel_cnt,
3837                                 default_channel_cnt, 0x0004,
3838                                 /* source sample freq 16khz */ true, /*add_csis*/
3839                                 true,                                /*add_cas*/
3840                                 true,                                /*add_pacs*/
3841                                 default_ase_cnt,                     /*add_ascs_cnt*/
3842                                 group_size, 1);
3843 
3844   const RawAddress test_address1 = GetTestAddress(1);
3845   SetSampleDatabaseEarbudsValid(2, test_address1, codec_spec_conf::kLeAudioLocationFrontRight,
3846                                 codec_spec_conf::kLeAudioLocationFrontRight, default_channel_cnt,
3847                                 default_channel_cnt, 0x0004,
3848                                 /* source sample freq 16khz */ true, /*add_csis*/
3849                                 true,                                /*add_cas*/
3850                                 true,                                /*add_pacs*/
3851                                 default_ase_cnt,                     /*add_ascs_cnt*/
3852                                 group_size, 2);
3853 
3854   // Load devices from the storage when storage API is called
3855   bool autoconnect = true;
3856   std::vector<uint8_t> empty_buf;
3857 
3858   EXPECT_CALL(mock_storage_load, Call()).WillOnce([&]() {
3859     do_in_main_thread(base::BindOnce(
3860             &LeAudioClient::AddFromStorage, test_address0, autoconnect,
3861             codec_spec_conf::kLeAudioLocationFrontLeft, codec_spec_conf::kLeAudioLocationFrontLeft,
3862             0xff, 0xff, std::move(empty_buf), std::move(empty_buf), std::move(empty_buf),
3863             std::move(empty_buf), std::move(empty_buf)));
3864     do_in_main_thread(base::BindOnce(&LeAudioClient::AddFromStorage, test_address1, autoconnect,
3865                                      codec_spec_conf::kLeAudioLocationFrontRight,
3866                                      codec_spec_conf::kLeAudioLocationFrontRight, 0xff, 0xff,
3867                                      std::move(empty_buf), std::move(empty_buf),
3868                                      std::move(empty_buf), std::move(empty_buf),
3869                                      std::move(empty_buf)));
3870     SyncOnMainLoop();
3871   });
3872 
3873   // Expect stored device0 to connect automatically (first directed connection )
3874   EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address0, BTM_BLE_DIRECT_CONNECTION, _))
3875           .Times(1);
3876 
3877   // Expect stored device1 to connect automatically (first direct connection)
3878   EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address1, BTM_BLE_DIRECT_CONNECTION, _))
3879           .Times(1);
3880 
3881   ON_CALL(mock_btm_interface_, BTM_IsEncrypted(test_address1, _))
3882           .WillByDefault(DoAll(Return(true)));
3883   ON_CALL(mock_btm_interface_, BTM_IsEncrypted(test_address0, _))
3884           .WillByDefault(DoAll(Return(true)));
3885 
3886   ON_CALL(mock_groups_module_, GetGroupId(_, _)).WillByDefault(DoAll(Return(group_id)));
3887 
3888   ON_CALL(mock_btm_interface_, GetSecurityFlagsByTransport(test_address0, NotNull(), _))
3889           .WillByDefault(DoAll(SetArgPointee<1>(BTM_SEC_FLAG_ENCRYPTED), Return(true)));
3890 
3891   std::vector<::bluetooth::le_audio::btle_audio_codec_config_t> framework_encode_preference;
3892 
3893   // Initialize
3894   BtaAppRegisterCallback app_register_callback;
3895   ON_CALL(mock_gatt_interface_, AppRegister(_, _, _, _))
3896           .WillByDefault(DoAll(SaveArg<1>(&gatt_callback), SaveArg<2>(&app_register_callback)));
3897   LeAudioClient::Initialize(
3898           &mock_audio_hal_client_callbacks_,
3899           base::Bind([](MockFunction<void()>* foo) { foo->Call(); }, &mock_storage_load),
3900           base::Bind([](MockFunction<bool()>* foo) { return foo->Call(); }, &mock_hal_2_1_verifier),
3901           framework_encode_preference);
3902   if (app_register_callback) {
3903     app_register_callback.Run(gatt_if, GATT_SUCCESS);
3904   }
3905 
3906   // We need to wait for the storage callback before verifying stuff
3907   SyncOnMainLoop();
3908   ASSERT_TRUE(LeAudioClient::IsLeAudioClientRunning());
3909   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
3910 
3911   // Simulate devices are not there and phone fallbacks to targeted
3912   // announcements
3913   EXPECT_CALL(mock_gatt_interface_,
3914               Open(gatt_if, test_address0, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _))
3915           .Times(1);
3916 
3917   EXPECT_CALL(mock_gatt_interface_,
3918               Open(gatt_if, test_address1, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _))
3919           .Times(1);
3920 
3921   // Devices not found
3922   InjectConnectedEvent(test_address0, 0, GATT_ERROR);
3923   InjectConnectedEvent(test_address1, 0, GATT_ERROR);
3924 
3925   SyncOnMainLoop();
3926   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
3927 
3928   /* Stack should rediscover services as storage is broken */
3929   EXPECT_CALL(mock_gatt_interface_, ServiceSearchRequest(2, _)).Times(1);
3930   EXPECT_CALL(mock_gatt_interface_, ServiceSearchRequest(1, _)).Times(1);
3931 
3932   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3933               OnConnectionState(ConnectionState::CONNECTED, test_address0))
3934           .Times(1);
3935 
3936   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3937               OnConnectionState(ConnectionState::CONNECTED, test_address1))
3938           .Times(1);
3939 
3940   /* For background connect, test needs to Inject Connected Event */
3941   InjectConnectedEvent(test_address0, 1);
3942   InjectConnectedEvent(test_address1, 2);
3943   SyncOnMainLoop();
3944 
3945   // Verify if all went well and we got the proper group
3946   std::vector<RawAddress> devs = LeAudioClient::Get()->GetGroupDevices(group_id);
3947   ASSERT_NE(std::find(devs.begin(), devs.end(), test_address0), devs.end());
3948   ASSERT_NE(std::find(devs.begin(), devs.end(), test_address1), devs.end());
3949 
3950   DisconnectLeAudioWithAclClose(test_address0, 1);
3951   DisconnectLeAudioWithAclClose(test_address1, 2);
3952 }
3953 
TEST_F(UnicastTestNoInit,LoadStoredEarbudsCsisGrouped)3954 TEST_F(UnicastTestNoInit, LoadStoredEarbudsCsisGrouped) {
3955   // Prepare two devices
3956   uint8_t group_size = 2;
3957   uint8_t group_id = 2;
3958 
3959   /* Prepare  mock to not inject connect event so the device can stay in
3960    * CONNECTING state*/
3961   ON_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_DIRECT_CONNECTION, false))
3962           .WillByDefault(DoAll(Return()));
3963 
3964   const RawAddress test_address0 = GetTestAddress(0);
3965   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationFrontLeft,
3966                                 codec_spec_conf::kLeAudioLocationFrontLeft, default_channel_cnt,
3967                                 default_channel_cnt, 0x0004,
3968                                 /* source sample freq 16khz */ true, /*add_csis*/
3969                                 true,                                /*add_cas*/
3970                                 true,                                /*add_pacs*/
3971                                 default_ase_cnt,                     /*add_ascs_cnt*/
3972                                 group_size, 1);
3973 
3974   const RawAddress test_address1 = GetTestAddress(1);
3975   SetSampleDatabaseEarbudsValid(2, test_address1, codec_spec_conf::kLeAudioLocationFrontRight,
3976                                 codec_spec_conf::kLeAudioLocationFrontRight, default_channel_cnt,
3977                                 default_channel_cnt, 0x0004,
3978                                 /* source sample freq 16khz */ true, /*add_csis*/
3979                                 true,                                /*add_cas*/
3980                                 true,                                /*add_pacs*/
3981                                 default_ase_cnt,                     /*add_ascs_cnt*/
3982                                 group_size, 2);
3983 
3984   // Load devices from the storage when storage API is called
3985   bool autoconnect = true;
3986 
3987   /* Common storage values */
3988   std::vector<uint8_t> handles;
3989   LeAudioClient::GetHandlesForStorage(test_address0, handles);
3990 
3991   std::vector<uint8_t> ases;
3992   LeAudioClient::GetAsesForStorage(test_address0, ases);
3993 
3994   std::vector<uint8_t> src_pacs;
3995   LeAudioClient::GetSourcePacsForStorage(test_address0, src_pacs);
3996 
3997   std::vector<uint8_t> snk_pacs;
3998   LeAudioClient::GetSinkPacsForStorage(test_address0, snk_pacs);
3999 
4000   std::vector<uint8_t> gmap_data;
4001   LeAudioClient::GetGmapForStorage(test_address0, gmap_data);
4002 
4003   EXPECT_CALL(mock_storage_load, Call()).WillOnce([&]() {
4004     do_in_main_thread(base::BindOnce(&LeAudioClient::AddFromStorage, test_address0, autoconnect,
4005                                      codec_spec_conf::kLeAudioLocationFrontLeft,
4006                                      codec_spec_conf::kLeAudioLocationFrontLeft, 0xff, 0xff,
4007                                      std::move(handles), std::move(snk_pacs), std::move(src_pacs),
4008                                      std::move(ases), std::move(gmap_data)));
4009     do_in_main_thread(base::BindOnce(&LeAudioClient::AddFromStorage, test_address1, autoconnect,
4010                                      codec_spec_conf::kLeAudioLocationFrontRight,
4011                                      codec_spec_conf::kLeAudioLocationFrontRight, 0xff, 0xff,
4012                                      std::move(handles), std::move(snk_pacs), std::move(src_pacs),
4013                                      std::move(ases), std::move(gmap_data)));
4014     SyncOnMainLoop();
4015   });
4016 
4017   // Expect stored device0 to connect automatically (first directed connection )
4018   EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address0, BTM_BLE_DIRECT_CONNECTION, _))
4019           .Times(1);
4020 
4021   // Expect stored device1 to connect automatically (first direct connection)
4022   EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address1, BTM_BLE_DIRECT_CONNECTION, _))
4023           .Times(1);
4024 
4025   ON_CALL(mock_btm_interface_, BTM_IsEncrypted(test_address1, _))
4026           .WillByDefault(DoAll(Return(true)));
4027   ON_CALL(mock_btm_interface_, BTM_IsEncrypted(test_address0, _))
4028           .WillByDefault(DoAll(Return(true)));
4029 
4030   ON_CALL(mock_groups_module_, GetGroupId(_, _)).WillByDefault(DoAll(Return(group_id)));
4031 
4032   ON_CALL(mock_btm_interface_, GetSecurityFlagsByTransport(test_address0, NotNull(), _))
4033           .WillByDefault(DoAll(SetArgPointee<1>(BTM_SEC_FLAG_ENCRYPTED), Return(true)));
4034 
4035   std::vector<::bluetooth::le_audio::btle_audio_codec_config_t> framework_encode_preference;
4036 
4037   // Initialize
4038   BtaAppRegisterCallback app_register_callback;
4039   ON_CALL(mock_gatt_interface_, AppRegister(_, _, _, _))
4040           .WillByDefault(DoAll(SaveArg<1>(&gatt_callback), SaveArg<2>(&app_register_callback)));
4041   LeAudioClient::Initialize(
4042           &mock_audio_hal_client_callbacks_,
4043           base::Bind([](MockFunction<void()>* foo) { foo->Call(); }, &mock_storage_load),
4044           base::Bind([](MockFunction<bool()>* foo) { return foo->Call(); }, &mock_hal_2_1_verifier),
4045           framework_encode_preference);
4046   if (app_register_callback) {
4047     app_register_callback.Run(gatt_if, GATT_SUCCESS);
4048   }
4049 
4050   // We need to wait for the storage callback before verifying stuff
4051   SyncOnMainLoop();
4052   ASSERT_TRUE(LeAudioClient::IsLeAudioClientRunning());
4053   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
4054 
4055   // Simulate devices are not there and phone fallbacks to targeted
4056   // announcements
4057   EXPECT_CALL(mock_gatt_interface_,
4058               Open(gatt_if, test_address0, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _))
4059           .Times(1);
4060 
4061   EXPECT_CALL(mock_gatt_interface_,
4062               Open(gatt_if, test_address1, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _))
4063           .Times(1);
4064 
4065   // Devices not found
4066   InjectConnectedEvent(test_address0, 0, GATT_ERROR);
4067   InjectConnectedEvent(test_address1, 0, GATT_ERROR);
4068 
4069   SyncOnMainLoop();
4070   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
4071 
4072   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4073               OnConnectionState(ConnectionState::CONNECTED, test_address0))
4074           .Times(1);
4075 
4076   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4077               OnConnectionState(ConnectionState::CONNECTED, test_address1))
4078           .Times(1);
4079 
4080   /* For background connect, test needs to Inject Connected Event */
4081   InjectConnectedEvent(test_address0, 1);
4082   InjectConnectedEvent(test_address1, 2);
4083   SyncOnMainLoop();
4084 
4085   // Verify if all went well and we got the proper group
4086   std::vector<RawAddress> devs = LeAudioClient::Get()->GetGroupDevices(group_id);
4087   ASSERT_NE(std::find(devs.begin(), devs.end(), test_address0), devs.end());
4088   ASSERT_NE(std::find(devs.begin(), devs.end(), test_address1), devs.end());
4089 
4090   DisconnectLeAudioWithAclClose(test_address0, 1);
4091   DisconnectLeAudioWithAclClose(test_address1, 2);
4092 }
4093 
TEST_F(UnicastTest,LoadStoredBandedHeadphones)4094 TEST_F(UnicastTest, LoadStoredBandedHeadphones) {
4095   const RawAddress test_address0 = GetTestAddress(0);
4096   uint16_t conn_id = 1;
4097 
4098   SetSampleDatabaseEarbudsValid(
4099           conn_id, test_address0,
4100           codec_spec_conf::kLeAudioLocationFrontLeft | codec_spec_conf::kLeAudioLocationFrontRight,
4101           codec_spec_conf::kLeAudioLocationMonoAudio, 2, 1, 0x0004,
4102           /* source sample freq 16khz */ false, /*add_csis*/
4103           true,                                 /*add_cas*/
4104           true,                                 /*add_pacs*/
4105           true,                                 /*add_ascs*/
4106           0, 0);
4107   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4108               OnConnectionState(ConnectionState::CONNECTED, test_address0))
4109           .Times(1);
4110 
4111   /* Connect and fill the device storage */
4112   ConnectLeAudio(test_address0);
4113 
4114   std::vector<uint8_t> handles;
4115   LeAudioClient::GetHandlesForStorage(test_address0, handles);
4116 
4117   std::vector<uint8_t> ases;
4118   LeAudioClient::GetAsesForStorage(test_address0, ases);
4119 
4120   std::vector<uint8_t> src_pacs;
4121   LeAudioClient::GetSourcePacsForStorage(test_address0, src_pacs);
4122 
4123   std::vector<uint8_t> snk_pacs;
4124   LeAudioClient::GetSinkPacsForStorage(test_address0, snk_pacs);
4125 
4126   std::vector<uint8_t> gmap_data;
4127   LeAudioClient::GetGmapForStorage(test_address0, gmap_data);
4128 
4129   /* Disconnect & Cleanup */
4130   DisconnectLeAudioWithAclClose(test_address0, conn_id);
4131   if (LeAudioClient::IsLeAudioClientRunning()) {
4132     LeAudioClient::Cleanup();
4133     ASSERT_FALSE(LeAudioClient::IsLeAudioClientRunning());
4134   }
4135 
4136   Mock::VerifyAndClearExpectations(&mock_hal_2_1_verifier);
4137   Mock::VerifyAndClearExpectations(&mock_storage_load);
4138 
4139   // Load devices from the storage when storage API is called
4140   bool autoconnect = true;
4141   EXPECT_CALL(mock_storage_load, Call()).WillOnce([&]() {
4142     do_in_main_thread(base::BindOnce(&LeAudioClient::AddFromStorage, test_address0, autoconnect,
4143                                      codec_spec_conf::kLeAudioLocationFrontLeft |
4144                                              codec_spec_conf::kLeAudioLocationFrontRight,
4145                                      codec_spec_conf::kLeAudioLocationMonoAudio, 0xff, 0xff,
4146                                      std::move(handles), std::move(snk_pacs), std::move(src_pacs),
4147                                      std::move(ases), std::move(gmap_data)));
4148     SyncOnMainLoop();
4149   });
4150 
4151   /* Prepare  mock to not inject connect event so the device can stay in
4152    * CONNECTING state*/
4153   ON_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_DIRECT_CONNECTION, false))
4154           .WillByDefault(DoAll(Return()));
4155 
4156   // Re-Initialize & load from storage
4157   BtaAppRegisterCallback app_register_callback;
4158   ON_CALL(mock_gatt_interface_, AppRegister(_, _, _, _))
4159           .WillByDefault(DoAll(SaveArg<1>(&gatt_callback), SaveArg<2>(&app_register_callback)));
4160   std::vector<::bluetooth::le_audio::btle_audio_codec_config_t> framework_encode_preference;
4161   LeAudioClient::Initialize(
4162           &mock_audio_hal_client_callbacks_,
4163           base::Bind([](MockFunction<void()>* foo) { foo->Call(); }, &mock_storage_load),
4164           base::Bind([](MockFunction<bool()>* foo) { return foo->Call(); }, &mock_hal_2_1_verifier),
4165           framework_encode_preference);
4166   if (app_register_callback) {
4167     app_register_callback.Run(gatt_if, GATT_SUCCESS);
4168   }
4169 
4170   InjectConnectedEvent(test_address0, conn_id);
4171   SyncOnMainLoop();
4172   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
4173 
4174   // Verify if all went well and we got the proper group
4175   auto group_id = MockDeviceGroups::DeviceGroups::Get()->GetGroupId(test_address0);
4176   std::vector<RawAddress> devs = LeAudioClient::Get()->GetGroupDevices(group_id);
4177   ASSERT_NE(std::find(devs.begin(), devs.end(), test_address0), devs.end());
4178 
4179   SetUpMockCodecManager(::bluetooth::le_audio::types::CodecLocation::HOST);
4180 
4181   // Start streaming
4182   LeAudioClient::Get()->GroupSetActive(group_id);
4183   SyncOnMainLoop();
4184 
4185   EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, _)).Times(1);
4186   EXPECT_CALL(mock_audio_hal_client_callbacks_, OnAudioGroupCurrentCodecConf(group_id, _, _))
4187           .Times(1);
4188   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
4189 
4190   SyncOnMainLoop();
4191   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
4192   Mock::VerifyAndClearExpectations(&mock_state_machine_);
4193 
4194   ASSERT_NE(0lu, streaming_groups.count(group_id));
4195   auto group = streaming_groups.at(group_id);
4196   ASSERT_NE(group, nullptr);
4197 
4198   auto device = group->GetFirstDevice();
4199   ASSERT_NE(device, nullptr);
4200   ASSERT_EQ(device->audio_directions_, bluetooth::le_audio::types::kLeAudioDirectionSink |
4201                                                bluetooth::le_audio::types::kLeAudioDirectionSource);
4202 
4203   DisconnectLeAudioWithAclClose(test_address0, conn_id);
4204 }
4205 
TEST_F(UnicastTestNoInit,ServiceChangedBeforeServiceIsConnected)4206 TEST_F(UnicastTestNoInit, ServiceChangedBeforeServiceIsConnected) {
4207   // Prepare two devices
4208   uint8_t group_size = 2;
4209   uint8_t group_id = 2;
4210 
4211   /* Prepare  mock to not inject connect event so the device can stay in
4212    * CONNECTING state*/
4213   ON_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_DIRECT_CONNECTION, false))
4214           .WillByDefault(DoAll(Return()));
4215 
4216   const RawAddress test_address0 = GetTestAddress(0);
4217   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationFrontLeft,
4218                                 codec_spec_conf::kLeAudioLocationFrontLeft, default_channel_cnt,
4219                                 default_channel_cnt, 0x0004,
4220                                 /* source sample freq 16khz */ true, /*add_csis*/
4221                                 true,                                /*add_cas*/
4222                                 true,                                /*add_pacs*/
4223                                 default_ase_cnt,                     /*add_ascs_cnt*/
4224                                 group_size, 1);
4225 
4226   const RawAddress test_address1 = GetTestAddress(1);
4227   SetSampleDatabaseEarbudsValid(2, test_address1, codec_spec_conf::kLeAudioLocationFrontRight,
4228                                 codec_spec_conf::kLeAudioLocationFrontRight, default_channel_cnt,
4229                                 default_channel_cnt, 0x0004,
4230                                 /* source sample freq 16khz */ true, /*add_csis*/
4231                                 true,                                /*add_cas*/
4232                                 true,                                /*add_pacs*/
4233                                 default_ase_cnt,                     /*add_ascs_cnt*/
4234                                 group_size, 2);
4235 
4236   // Load devices from the storage when storage API is called
4237   bool autoconnect = true;
4238 
4239   /* Common storage values */
4240   std::vector<uint8_t> handles;
4241   LeAudioClient::GetHandlesForStorage(test_address0, handles);
4242 
4243   std::vector<uint8_t> ases;
4244   LeAudioClient::GetAsesForStorage(test_address0, ases);
4245 
4246   std::vector<uint8_t> src_pacs;
4247   LeAudioClient::GetSourcePacsForStorage(test_address0, src_pacs);
4248 
4249   std::vector<uint8_t> snk_pacs;
4250   LeAudioClient::GetSinkPacsForStorage(test_address0, snk_pacs);
4251 
4252   std::vector<uint8_t> gmap_data;
4253   LeAudioClient::GetGmapForStorage(test_address0, gmap_data);
4254 
4255   EXPECT_CALL(mock_storage_load, Call()).WillOnce([&]() {
4256     do_in_main_thread(base::BindOnce(&LeAudioClient::AddFromStorage, test_address0, autoconnect,
4257                                      codec_spec_conf::kLeAudioLocationFrontLeft,
4258                                      codec_spec_conf::kLeAudioLocationFrontLeft, 0xff, 0xff,
4259                                      std::move(handles), std::move(snk_pacs), std::move(src_pacs),
4260                                      std::move(ases), std::move(gmap_data)));
4261     do_in_main_thread(base::BindOnce(&LeAudioClient::AddFromStorage, test_address1, autoconnect,
4262                                      codec_spec_conf::kLeAudioLocationFrontRight,
4263                                      codec_spec_conf::kLeAudioLocationFrontRight, 0xff, 0xff,
4264                                      std::move(handles), std::move(snk_pacs), std::move(src_pacs),
4265                                      std::move(ases), std::move(gmap_data)));
4266     SyncOnMainLoop();
4267   });
4268 
4269   // Expect stored device0 to connect automatically (first directed connection )
4270   EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address0, BTM_BLE_DIRECT_CONNECTION, _))
4271           .Times(1);
4272 
4273   // Expect stored device1 to connect automatically (first direct connection)
4274   EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address1, BTM_BLE_DIRECT_CONNECTION, _))
4275           .Times(1);
4276 
4277   ON_CALL(mock_btm_interface_, BTM_IsEncrypted(test_address1, _))
4278           .WillByDefault(DoAll(Return(true)));
4279   ON_CALL(mock_btm_interface_, BTM_IsEncrypted(test_address0, _))
4280           .WillByDefault(DoAll(Return(true)));
4281 
4282   ON_CALL(mock_groups_module_, GetGroupId(_, _)).WillByDefault(DoAll(Return(group_id)));
4283 
4284   ON_CALL(mock_btm_interface_, GetSecurityFlagsByTransport(test_address0, NotNull(), _))
4285           .WillByDefault(DoAll(SetArgPointee<1>(BTM_SEC_FLAG_ENCRYPTED), Return(true)));
4286 
4287   std::vector<::bluetooth::le_audio::btle_audio_codec_config_t> framework_encode_preference;
4288 
4289   // Initialize
4290   BtaAppRegisterCallback app_register_callback;
4291   ON_CALL(mock_gatt_interface_, AppRegister(_, _, _, _))
4292           .WillByDefault(DoAll(SaveArg<1>(&gatt_callback), SaveArg<2>(&app_register_callback)));
4293   LeAudioClient::Initialize(
4294           &mock_audio_hal_client_callbacks_,
4295           base::Bind([](MockFunction<void()>* foo) { foo->Call(); }, &mock_storage_load),
4296           base::Bind([](MockFunction<bool()>* foo) { return foo->Call(); }, &mock_hal_2_1_verifier),
4297           framework_encode_preference);
4298   if (app_register_callback) {
4299     app_register_callback.Run(gatt_if, GATT_SUCCESS);
4300   }
4301 
4302   // We need to wait for the storage callback before verifying stuff
4303   SyncOnMainLoop();
4304   ASSERT_TRUE(LeAudioClient::IsLeAudioClientRunning());
4305   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
4306 
4307   /* Inject Service Changed */
4308   InjectServiceChangedEvent(test_address1, 0xffff);
4309   SyncOnMainLoop();
4310   InjectServiceChangedEvent(test_address0, 0xffff);
4311   SyncOnMainLoop();
4312   /* Stack should rediscover services as storage is broken */
4313   EXPECT_CALL(mock_gatt_interface_, ServiceSearchRequest(2, _)).Times(1);
4314   EXPECT_CALL(mock_gatt_interface_, ServiceSearchRequest(1, _)).Times(1);
4315 
4316   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4317               OnConnectionState(ConnectionState::CONNECTED, test_address0))
4318           .Times(1);
4319 
4320   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4321               OnConnectionState(ConnectionState::CONNECTED, test_address1))
4322           .Times(1);
4323 
4324   /* For background connect, test needs to Inject Connected Event */
4325   InjectConnectedEvent(test_address0, 1);
4326   InjectConnectedEvent(test_address1, 2);
4327   SyncOnMainLoop();
4328 
4329   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
4330   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
4331 }
4332 
TEST_F(UnicastTestNoInit,LoadStoredEarbudsCsisGroupedDifferently)4333 TEST_F(UnicastTestNoInit, LoadStoredEarbudsCsisGroupedDifferently) {
4334   // Prepare two devices
4335   uint8_t group_size = 1;
4336 
4337   // Device 0
4338   uint8_t group_id0 = 2;
4339   bool autoconnect0 = true;
4340   const RawAddress test_address0 = GetTestAddress(0);
4341   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationFrontLeft,
4342                                 codec_spec_conf::kLeAudioLocationFrontLeft, 0x0004,
4343                                 /* source sample freq 16khz */ true, /*add_csis*/
4344                                 true,                                /*add_cas*/
4345                                 true,                                /*add_pacs*/
4346                                 true,                                /*add_ascs*/
4347                                 group_size, 1);
4348 
4349   ON_CALL(mock_groups_module_, GetGroupId(test_address0, _))
4350           .WillByDefault(DoAll(Return(group_id0)));
4351 
4352   // Device 1
4353   uint8_t group_id1 = 3;
4354   bool autoconnect1 = false;
4355   const RawAddress test_address1 = GetTestAddress(1);
4356   SetSampleDatabaseEarbudsValid(2, test_address1, codec_spec_conf::kLeAudioLocationFrontRight,
4357                                 codec_spec_conf::kLeAudioLocationFrontRight, default_channel_cnt,
4358                                 default_channel_cnt, 0x0004,
4359                                 /* source sample freq 16khz */ true, /*add_csis*/
4360                                 true,                                /*add_cas*/
4361                                 true,                                /*add_pacs*/
4362                                 default_ase_cnt,                     /*add_ascs_cnt*/
4363                                 group_size, 2);
4364 
4365   ON_CALL(mock_groups_module_, GetGroupId(test_address1, _))
4366           .WillByDefault(DoAll(Return(group_id1)));
4367 
4368   /* Commont storage values */
4369   std::vector<uint8_t> handles;
4370   LeAudioClient::GetHandlesForStorage(test_address0, handles);
4371 
4372   std::vector<uint8_t> ases;
4373   LeAudioClient::GetAsesForStorage(test_address0, ases);
4374 
4375   std::vector<uint8_t> src_pacs;
4376   LeAudioClient::GetSourcePacsForStorage(test_address0, src_pacs);
4377 
4378   std::vector<uint8_t> snk_pacs;
4379   LeAudioClient::GetSinkPacsForStorage(test_address0, snk_pacs);
4380 
4381   std::vector<uint8_t> gmap_data;
4382   LeAudioClient::GetGmapForStorage(test_address0, gmap_data);
4383 
4384   // Load devices from the storage when storage API is called
4385   EXPECT_CALL(mock_storage_load, Call()).WillOnce([&]() {
4386     do_in_main_thread(base::BindOnce(&LeAudioClient::AddFromStorage, test_address0, autoconnect0,
4387                                      codec_spec_conf::kLeAudioLocationFrontLeft,
4388                                      codec_spec_conf::kLeAudioLocationFrontLeft, 0xff, 0xff,
4389                                      std::move(handles), std::move(snk_pacs), std::move(src_pacs),
4390                                      std::move(ases), std::move(gmap_data)));
4391     do_in_main_thread(base::BindOnce(&LeAudioClient::AddFromStorage, test_address1, autoconnect1,
4392                                      codec_spec_conf::kLeAudioLocationFrontRight,
4393                                      codec_spec_conf::kLeAudioLocationFrontRight, 0xff, 0xff,
4394                                      std::move(handles), std::move(snk_pacs), std::move(src_pacs),
4395                                      std::move(ases), std::move(gmap_data)));
4396   });
4397 
4398   // Expect stored device0 to connect automatically
4399   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4400               OnConnectionState(ConnectionState::CONNECTED, test_address0))
4401           .Times(1);
4402   ON_CALL(mock_btm_interface_, BTM_IsEncrypted(test_address0, _))
4403           .WillByDefault(DoAll(Return(true)));
4404 
4405   // First device will got connected
4406   EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address0, BTM_BLE_DIRECT_CONNECTION, _))
4407           .Times(1);
4408   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, _)).Times(1);
4409   EXPECT_CALL(mock_gatt_interface_,
4410               Open(gatt_if, test_address0, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _))
4411           .Times(1);
4412 
4413   // Expect stored device1 to NOT connect automatically
4414   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4415               OnConnectionState(ConnectionState::CONNECTED, test_address1))
4416           .Times(0);
4417   ON_CALL(mock_btm_interface_, BTM_IsEncrypted(test_address1, _))
4418           .WillByDefault(DoAll(Return(true)));
4419 
4420   EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address1, BTM_BLE_DIRECT_CONNECTION, _))
4421           .Times(0);
4422 
4423   // Initialize
4424   BtaAppRegisterCallback app_register_callback;
4425   ON_CALL(mock_gatt_interface_, AppRegister(_, _, _, _))
4426           .WillByDefault(DoAll(SaveArg<1>(&gatt_callback), SaveArg<2>(&app_register_callback)));
4427   std::vector<::bluetooth::le_audio::btle_audio_codec_config_t> framework_encode_preference;
4428   LeAudioClient::Initialize(
4429           &mock_audio_hal_client_callbacks_,
4430           base::Bind([](MockFunction<void()>* foo) { foo->Call(); }, &mock_storage_load),
4431           base::Bind([](MockFunction<bool()>* foo) { return foo->Call(); }, &mock_hal_2_1_verifier),
4432           framework_encode_preference);
4433   if (app_register_callback) {
4434     app_register_callback.Run(gatt_if, GATT_SUCCESS);
4435   }
4436 
4437   // We need to wait for the storage callback before verifying stuff
4438   SyncOnMainLoop();
4439   ASSERT_TRUE(LeAudioClient::IsLeAudioClientRunning());
4440   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
4441   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
4442 
4443   // Simulate device is not there and phone fallbacks to targeted announcements
4444   EXPECT_CALL(mock_gatt_interface_,
4445               Open(gatt_if, test_address0, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _))
4446           .Times(1);
4447 
4448   // Devices 0 is connected. Disconnect it
4449   InjectDisconnectedEvent(1, GATT_CONN_TERMINATE_PEER_USER);
4450 
4451   SyncOnMainLoop();
4452   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
4453 
4454   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, _)).Times(1);
4455   EXPECT_CALL(mock_gatt_interface_,
4456               Open(gatt_if, test_address0, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _))
4457           .Times(1);
4458 
4459   /* Keep device in Getting Ready state */
4460   ON_CALL(mock_btm_interface_, BTM_IsEncrypted(test_address0, _))
4461           .WillByDefault(DoAll(Return(false)));
4462   ON_CALL(mock_btm_interface_, SetEncryption(test_address0, _, _, _, _))
4463           .WillByDefault(Return(tBTM_STATUS::BTM_SUCCESS));
4464 
4465   /* For background connect, test needs to Inject Connected Event */
4466   InjectConnectedEvent(test_address0, 1);
4467 
4468   // We need to wait for the storage callback before verifying stuff
4469   SyncOnMainLoop();
4470   ASSERT_TRUE(LeAudioClient::IsLeAudioClientRunning());
4471   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
4472 
4473   std::vector<RawAddress> devs = LeAudioClient::Get()->GetGroupDevices(group_id0);
4474   ASSERT_NE(std::find(devs.begin(), devs.end(), test_address0), devs.end());
4475   ASSERT_EQ(std::find(devs.begin(), devs.end(), test_address1), devs.end());
4476 
4477   devs = LeAudioClient::Get()->GetGroupDevices(group_id1);
4478   ASSERT_EQ(std::find(devs.begin(), devs.end(), test_address0), devs.end());
4479   ASSERT_NE(std::find(devs.begin(), devs.end(), test_address1), devs.end());
4480 
4481   /* Disconnects while being in getting ready state */
4482   DisconnectLeAudioWithGattClose(test_address0, 1);
4483 }
4484 
TEST_F(UnicastTest,GroupingAddRemove)4485 TEST_F(UnicastTest, GroupingAddRemove) {
4486   // Earbud connects without known grouping
4487   uint8_t group_id0 = bluetooth::groups::kGroupUnknown;
4488   const RawAddress test_address0 = GetTestAddress(0);
4489 
4490   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
4491   ConnectNonCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
4492                        codec_spec_conf::kLeAudioLocationFrontLeft);
4493 
4494   group_id0 = MockDeviceGroups::DeviceGroups::Get()->GetGroupId(test_address0);
4495 
4496   // Earbud connects without known grouping
4497   uint8_t group_id1 = bluetooth::groups::kGroupUnknown;
4498   const RawAddress test_address1 = GetTestAddress(1);
4499   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
4500   ConnectNonCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
4501                        codec_spec_conf::kLeAudioLocationFrontRight);
4502 
4503   group_id1 = MockDeviceGroups::DeviceGroups::Get()->GetGroupId(test_address1);
4504 
4505   Mock::VerifyAndClearExpectations(&mock_btif_storage_);
4506 
4507   // Verify individual groups
4508   ASSERT_NE(group_id0, bluetooth::groups::kGroupUnknown);
4509   ASSERT_NE(group_id1, bluetooth::groups::kGroupUnknown);
4510   ASSERT_NE(group_id0, group_id1);
4511   ASSERT_EQ(LeAudioClient::Get()->GetGroupDevices(group_id0).size(), 1u);
4512   ASSERT_EQ(LeAudioClient::Get()->GetGroupDevices(group_id1).size(), 1u);
4513 
4514   // Expectations on reassigning second earbud to the first group
4515   int dev1_storage_group = bluetooth::groups::kGroupUnknown;
4516   int dev1_new_group = bluetooth::groups::kGroupUnknown;
4517 
4518   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4519               OnGroupNodeStatus(test_address1, group_id1, GroupNodeStatus::REMOVED))
4520           .Times(AtLeast(1));
4521   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4522               OnGroupNodeStatus(test_address1, _, GroupNodeStatus::ADDED))
4523           .WillRepeatedly(SaveArg<1>(&dev1_new_group));
4524   EXPECT_CALL(mock_groups_module_, RemoveDevice(test_address1, group_id1)).Times(AtLeast(1));
4525   EXPECT_CALL(mock_groups_module_, AddDevice(test_address1, _, _)).Times(AnyNumber());
4526 
4527   LeAudioClient::Get()->GroupRemoveNode(group_id1, test_address1);
4528   SyncOnMainLoop();
4529 
4530   Mock::VerifyAndClearExpectations(&mock_groups_module_);
4531   Mock::VerifyAndClearExpectations(&mock_btif_storage_);
4532 
4533   EXPECT_CALL(mock_groups_module_, AddDevice(test_address1, _, group_id0)).Times(1);
4534 
4535   LeAudioClient::Get()->GroupAddNode(group_id0, test_address1);
4536   SyncOnMainLoop();
4537   Mock::VerifyAndClearExpectations(&mock_groups_module_);
4538 
4539   dev1_storage_group = MockDeviceGroups::DeviceGroups::Get()->GetGroupId(test_address1);
4540 
4541   // Verify regrouping results
4542   EXPECT_EQ(dev1_new_group, group_id0);
4543   EXPECT_EQ(dev1_new_group, dev1_storage_group);
4544   ASSERT_EQ(LeAudioClient::Get()->GetGroupDevices(group_id1).size(), 0u);
4545   ASSERT_EQ(LeAudioClient::Get()->GetGroupDevices(group_id0).size(), 2u);
4546   std::vector<RawAddress> devs = LeAudioClient::Get()->GetGroupDevices(group_id0);
4547   ASSERT_NE(std::find(devs.begin(), devs.end(), test_address0), devs.end());
4548   ASSERT_NE(std::find(devs.begin(), devs.end(), test_address1), devs.end());
4549 }
4550 
TEST_F(UnicastTest,DoubleResumeFromAF)4551 TEST_F(UnicastTest, DoubleResumeFromAF) {
4552   const RawAddress test_address0 = GetTestAddress(0);
4553   int group_id = bluetooth::groups::kGroupUnknown;
4554 
4555   SetSampleDatabaseEarbudsValid(
4556           1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
4557           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
4558           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
4559           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
4560   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4561               OnConnectionState(ConnectionState::CONNECTED, test_address0))
4562           .Times(1);
4563   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4564               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
4565           .WillOnce(DoAll(SaveArg<1>(&group_id)));
4566 
4567   ConnectLeAudio(test_address0);
4568   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
4569 
4570   constexpr int gmcs_ccid = 1;
4571   constexpr int gtbs_ccid = 2;
4572 
4573   // Audio sessions are started only when device gets active
4574   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
4575   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
4576   LeAudioClient::Get()->SetCcidInformation(gmcs_ccid, 4 /* Media */);
4577   LeAudioClient::Get()->SetCcidInformation(gtbs_ccid, 2 /* Phone */);
4578   LeAudioClient::Get()->GroupSetActive(group_id);
4579   SyncOnMainLoop();
4580 
4581   types::BidirectionalPair<std::vector<uint8_t>> ccids = {.sink = {gmcs_ccid}, .source = {}};
4582   EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, ccids)).Times(1);
4583 
4584   stay_at_qos_config_in_start_stream = true;
4585 
4586   UpdateLocalSourceMetadata(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC);
4587   LocalAudioSourceResume(false);
4588 
4589   SyncOnMainLoop();
4590   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
4591   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
4592 
4593   // Additional resume shall be ignored.
4594   LocalAudioSourceResume(false, false);
4595 
4596   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(0);
4597 
4598   do_in_main_thread(base::BindOnce(
4599           [](int group_id,
4600              bluetooth::le_audio::LeAudioGroupStateMachine::Callbacks* state_machine_callbacks) {
4601             state_machine_callbacks->StatusReportCb(group_id, GroupStreamStatus::STREAMING);
4602           },
4603           group_id, base::Unretained(state_machine_callbacks_)));
4604   SyncOnMainLoop();
4605   Mock::VerifyAndClearExpectations(&mock_state_machine_);
4606 
4607   // Verify Data transfer on one audio source cis
4608   constexpr uint8_t cis_count_out = 1;
4609   constexpr uint8_t cis_count_in = 0;
4610   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
4611 }
4612 
TEST_F(UnicastTest,DoubleResumeFromAFOnLocalSink)4613 TEST_F(UnicastTest, DoubleResumeFromAFOnLocalSink) {
4614   const RawAddress test_address0 = GetTestAddress(0);
4615   int group_id = bluetooth::groups::kGroupUnknown;
4616 
4617   default_channel_cnt = 1;
4618 
4619   SetSampleDatabaseEarbudsValid(
4620           1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
4621           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
4622           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
4623           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
4624   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4625               OnConnectionState(ConnectionState::CONNECTED, test_address0))
4626           .Times(1);
4627   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4628               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
4629           .WillOnce(DoAll(SaveArg<1>(&group_id)));
4630 
4631   ConnectLeAudio(test_address0);
4632   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
4633 
4634   // Audio sessions are started only when device gets active
4635   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
4636   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
4637   LeAudioClient::Get()->GroupSetActive(group_id);
4638   SyncOnMainLoop();
4639 
4640   EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, _)).Times(1);
4641 
4642   stay_at_qos_config_in_start_stream = true;
4643 
4644   UpdateLocalSinkMetadata(AUDIO_SOURCE_MIC);
4645   LocalAudioSinkResume();
4646 
4647   SyncOnMainLoop();
4648   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
4649   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
4650 
4651   EXPECT_CALL(*mock_le_audio_sink_hal_client_, CancelStreamingRequest()).Times(0);
4652 
4653   // Actuall test here: send additional resume which shall be ignored.
4654   LocalAudioSinkResume();
4655 
4656   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(0);
4657 
4658   do_in_main_thread(base::BindOnce(
4659           [](int group_id,
4660              bluetooth::le_audio::LeAudioGroupStateMachine::Callbacks* state_machine_callbacks) {
4661             state_machine_callbacks->StatusReportCb(group_id, GroupStreamStatus::STREAMING);
4662           },
4663           group_id, base::Unretained(state_machine_callbacks_)));
4664   SyncOnMainLoop();
4665   Mock::VerifyAndClearExpectations(&mock_state_machine_);
4666 
4667   // Verify Data transfer on local audio sink which is started
4668   constexpr uint8_t cis_count_out = 0;
4669   constexpr uint8_t cis_count_in = 1;
4670   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 0, 40);
4671 }
4672 
TEST_F(UnicastTest,HandleResumeWithoutMetadataUpdateOnLocalSink)4673 TEST_F(UnicastTest, HandleResumeWithoutMetadataUpdateOnLocalSink) {
4674   const RawAddress test_address0 = GetTestAddress(0);
4675   int group_id = bluetooth::groups::kGroupUnknown;
4676 
4677   /**
4678    * In this test we want to make sure that if MetadataUpdate is
4679    * not called before Resume, but the context type is supported,
4680    * stream should be created
4681    */
4682 
4683   default_channel_cnt = 1;
4684 
4685   SetSampleDatabaseEarbudsValid(
4686           1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
4687           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
4688           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
4689           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
4690   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4691               OnConnectionState(ConnectionState::CONNECTED, test_address0))
4692           .Times(1);
4693   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4694               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
4695           .WillOnce(DoAll(SaveArg<1>(&group_id)));
4696 
4697   ConnectLeAudio(test_address0);
4698   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
4699 
4700   // Audio sessions are started only when device gets active
4701   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
4702   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
4703   LeAudioClient::Get()->GroupSetActive(group_id);
4704   SyncOnMainLoop();
4705 
4706   EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, _)).Times(1);
4707 
4708   UpdateLocalSinkMetadata(AUDIO_SOURCE_MIC);
4709   LocalAudioSinkResume();
4710 
4711   SyncOnMainLoop();
4712   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
4713   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
4714   Mock::VerifyAndClearExpectations(&mock_state_machine_);
4715 
4716   // Verify Data transfer on local audio sink which is started
4717   constexpr uint8_t cis_count_out = 0;
4718   constexpr uint8_t cis_count_in = 1;
4719   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 0, 40);
4720 
4721   SyncOnMainLoop();
4722   /* Clear cache by changing context types, this is required for the test
4723    * as setting active device actually generate cache
4724    */
4725   auto sink_available_context = types::kLeAudioContextAllRemoteSinkOnly;
4726   auto source_available_context = types::kLeAudioContextAllRemoteSource;
4727   InjectAvailableContextTypes(test_address0, 1, sink_available_context, source_available_context);
4728 
4729   StopStreaming(group_id, true);
4730   SyncOnMainLoop();
4731 
4732   // simulate suspend timeout passed, alarm executing
4733   fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
4734   SyncOnMainLoop();
4735 
4736   EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, _)).Times(1);
4737 
4738   // Resume without metadata update while cached configuration is cleared
4739   LocalAudioSinkResume();
4740   SyncOnMainLoop();
4741   Mock::VerifyAndClearExpectations(&mock_state_machine_);
4742 }
4743 
TEST_F(UnicastTest,GroupSetActiveNonConnectedGroup)4744 TEST_F(UnicastTest, GroupSetActiveNonConnectedGroup) {
4745   const RawAddress test_address0 = GetTestAddress(0);
4746   int group_id = bluetooth::groups::kGroupUnknown;
4747 
4748   /**
4749    * In this test we want to make sure that Available context change reach Java
4750    * when group is in Configured state
4751    */
4752 
4753   default_channel_cnt = 1;
4754   int conn_id = 1;
4755   SetSampleDatabaseEarbudsValid(
4756           conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo,
4757           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
4758           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
4759           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
4760   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4761               OnConnectionState(ConnectionState::CONNECTED, test_address0))
4762           .Times(1);
4763   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4764               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
4765           .WillOnce(DoAll(SaveArg<1>(&group_id)));
4766 
4767   ConnectLeAudio(test_address0);
4768   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
4769 
4770   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
4771 
4772   EXPECT_CALL(mock_audio_hal_client_callbacks_, OnGroupStatus(group_id, GroupStatus::INACTIVE))
4773           .Times(1);
4774 
4775   InjectDisconnectedEvent(conn_id);
4776   SyncOnMainLoop();
4777 
4778   // Audio sessions are started only when device gets active
4779   EXPECT_CALL(mock_audio_hal_client_callbacks_, OnAudioGroupSelectableCodecConf(group_id, _, _))
4780           .Times(0);
4781   EXPECT_CALL(mock_audio_hal_client_callbacks_, OnAudioGroupCurrentCodecConf(group_id, _, _))
4782           .Times(0);
4783   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(0);
4784   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(0);
4785 
4786   // try to set active group on non connected group
4787 
4788   LeAudioClient::Get()->GroupSetActive(group_id);
4789   SyncOnMainLoop();
4790   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
4791   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
4792 }
4793 
TEST_F(UnicastTest,GroupSetActive_CurrentCodecSentOfActive)4794 TEST_F(UnicastTest, GroupSetActive_CurrentCodecSentOfActive) {
4795   const RawAddress test_address0 = GetTestAddress(0);
4796   int group_id = bluetooth::groups::kGroupUnknown;
4797 
4798   /**
4799    * In this test we want to make sure that Available context change reach Java
4800    * when group is in Configured state
4801    */
4802 
4803   default_channel_cnt = 1;
4804 
4805   SetSampleDatabaseEarbudsValid(
4806           1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
4807           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
4808           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
4809           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
4810   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4811               OnConnectionState(ConnectionState::CONNECTED, test_address0))
4812           .Times(1);
4813   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4814               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
4815           .WillOnce(DoAll(SaveArg<1>(&group_id)));
4816 
4817   ConnectLeAudio(test_address0);
4818   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
4819 
4820   // Audio sessions are started only when device gets active
4821   EXPECT_CALL(mock_audio_hal_client_callbacks_, OnAudioGroupSelectableCodecConf(group_id, _, _))
4822           .Times(1);
4823   btle_audio_codec_config_t empty_conf{};
4824   btle_audio_codec_config_t output_config = {
4825           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
4826           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_48000HZ,
4827           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
4828           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
4829           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
4830           .octets_per_frame = 120};
4831 
4832   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4833               OnAudioGroupCurrentCodecConf(group_id, empty_conf, output_config))
4834           .Times(1);
4835 
4836   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
4837   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
4838   LeAudioClient::Get()->GroupSetActive(group_id);
4839   SyncOnMainLoop();
4840   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
4841   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
4842 }
4843 
TEST_F(UnicastTest,GroupSetActive)4844 TEST_F(UnicastTest, GroupSetActive) {
4845   const RawAddress test_address0 = GetTestAddress(0);
4846   int group_id = bluetooth::groups::kGroupUnknown;
4847 
4848   /**
4849    * In this test we want to make sure that Available context change reach Java
4850    * when group is in Configured state
4851    */
4852 
4853   default_channel_cnt = 1;
4854 
4855   SetSampleDatabaseEarbudsValid(
4856           1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
4857           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
4858           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
4859           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
4860   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4861               OnConnectionState(ConnectionState::CONNECTED, test_address0))
4862           .Times(1);
4863   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4864               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
4865           .WillOnce(DoAll(SaveArg<1>(&group_id)));
4866 
4867   ConnectLeAudio(test_address0);
4868   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
4869 
4870   // Audio sessions are started only when device gets active
4871   EXPECT_CALL(mock_audio_hal_client_callbacks_, OnAudioGroupSelectableCodecConf(group_id, _, _))
4872           .Times(1);
4873   EXPECT_CALL(mock_audio_hal_client_callbacks_, OnGroupStatus(group_id, GroupStatus::ACTIVE))
4874           .Times(1);
4875   EXPECT_CALL(mock_audio_hal_client_callbacks_, OnGroupStatus(_, GroupStatus::INACTIVE)).Times(0);
4876   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
4877   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
4878 
4879   EXPECT_CALL(*mock_codec_manager_,
4880               UpdateActiveUnicastAudioHalClient(mock_le_audio_source_hal_client_,
4881                                                 mock_le_audio_sink_hal_client_, true))
4882           .Times(1);
4883 
4884   LeAudioClient::Get()->GroupSetActive(group_id);
4885   SyncOnMainLoop();
4886   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
4887   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
4888   Mock::VerifyAndClearExpectations(mock_codec_manager_);
4889 }
4890 
TEST_F(UnicastTest,GroupSetActive_SinkPacksEmpty)4891 TEST_F(UnicastTest, GroupSetActive_SinkPacksEmpty) {
4892   const RawAddress test_address0 = GetTestAddress(0);
4893   int group_id = bluetooth::groups::kGroupUnknown;
4894   empty_sink_pack_ = true;
4895 
4896   /**
4897    * In this test we want to make sure that Available context change reach Java
4898    * when group is in Configured state
4899    */
4900 
4901   default_channel_cnt = 1;
4902 
4903   SetSampleDatabaseEarbudsValid(
4904           1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
4905           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
4906           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
4907           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
4908   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4909               OnConnectionState(ConnectionState::CONNECTED, test_address0))
4910           .Times(1);
4911   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4912               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
4913           .WillOnce(DoAll(SaveArg<1>(&group_id)));
4914 
4915   ConnectLeAudio(test_address0);
4916   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
4917 
4918   // Audio sessions are started only when device gets active
4919   std::vector<btle_audio_codec_config_t> empty_confs;
4920 
4921   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4922               OnAudioGroupSelectableCodecConf(group_id, _, empty_confs))
4923           .Times(1);
4924   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
4925   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
4926 
4927   EXPECT_CALL(*mock_codec_manager_,
4928               UpdateActiveUnicastAudioHalClient(mock_le_audio_source_hal_client_,
4929                                                 mock_le_audio_sink_hal_client_, true))
4930           .Times(1);
4931 
4932   LeAudioClient::Get()->GroupSetActive(group_id);
4933   SyncOnMainLoop();
4934   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
4935   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
4936   Mock::VerifyAndClearExpectations(mock_codec_manager_);
4937 }
4938 
TEST_F(UnicastTest,GroupSetActive_SourcePacksEmpty)4939 TEST_F(UnicastTest, GroupSetActive_SourcePacksEmpty) {
4940   const RawAddress test_address0 = GetTestAddress(0);
4941   int group_id = bluetooth::groups::kGroupUnknown;
4942   empty_source_pack_ = true;
4943 
4944   /**
4945    * In this test we want to make sure that Available context change reach Java
4946    * when group is in Configured state
4947    */
4948 
4949   default_channel_cnt = 1;
4950 
4951   SetSampleDatabaseEarbudsValid(
4952           1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
4953           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
4954           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
4955           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
4956   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4957               OnConnectionState(ConnectionState::CONNECTED, test_address0))
4958           .Times(1);
4959   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4960               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
4961           .WillOnce(DoAll(SaveArg<1>(&group_id)));
4962 
4963   ConnectLeAudio(test_address0);
4964   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
4965 
4966   // Audio sessions are started only when device gets active
4967   std::vector<btle_audio_codec_config_t> empty_confs;
4968 
4969   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4970               OnAudioGroupSelectableCodecConf(group_id, empty_confs, _))
4971           .Times(1);
4972   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
4973   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
4974   LeAudioClient::Get()->GroupSetActive(group_id);
4975   SyncOnMainLoop();
4976   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
4977   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
4978 }
4979 
TEST_F(UnicastTest,GroupSetActive_and_InactiveDuringStreamConfiguration)4980 TEST_F(UnicastTest, GroupSetActive_and_InactiveDuringStreamConfiguration) {
4981   const RawAddress test_address0 = GetTestAddress(0);
4982   int group_id = bluetooth::groups::kGroupUnknown;
4983   empty_source_pack_ = true;
4984 
4985   /**
4986    * In this test we want to make sure that StopStream is called when group is set to inactive
4987    * while being between IDLE and CONFIGURED state
4988    */
4989 
4990   default_channel_cnt = 1;
4991 
4992   SetSampleDatabaseEarbudsValid(
4993           1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
4994           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
4995           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
4996           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
4997   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4998               OnConnectionState(ConnectionState::CONNECTED, test_address0))
4999           .Times(1);
5000   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5001               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
5002           .WillOnce(DoAll(SaveArg<1>(&group_id)));
5003 
5004   ConnectLeAudio(test_address0);
5005   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
5006 
5007   EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, _)).Times(1);
5008 
5009   stay_at_qos_config_in_start_stream = true;
5010 
5011   LeAudioClient::Get()->GroupSetActive(group_id);
5012   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id, AUDIO_SOURCE_INVALID, false,
5013                  false);
5014 
5015   SyncOnMainLoop();
5016 
5017   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(1);
5018   LeAudioClient::Get()->GroupSetActive(bluetooth::groups::kGroupUnknown);
5019 
5020   SyncOnMainLoop();
5021   Mock::VerifyAndClearExpectations(&mock_state_machine_);
5022 }
5023 
TEST_F(UnicastTest,AnotherGroupSetActive_DuringMediaStream)5024 TEST_F(UnicastTest, AnotherGroupSetActive_DuringMediaStream) {
5025   const RawAddress test_address0 = GetTestAddress(0);
5026   const RawAddress test_address1 = GetTestAddress(1);
5027   int group_id_1 = 1;
5028   int group_id_2 = 2;
5029   int group_size = 1;
5030 
5031   default_channel_cnt = 2;
5032   default_src_channel_cnt = 1;
5033 
5034   /**
5035    * Scenario:
5036    * 1. Voip is started
5037    * 2. Group 1 is set active - no fast configuration is expected
5038    * 3. Audio HAL resumse the stream and Group 1 is streaming
5039    * 3. Group 2 is set to active - it is expected that stream to Group 1 is stopped and Group 2
5040    * configuration goes to QoS configured
5041    */
5042   // Report working CSIS
5043   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
5044   ON_CALL(mock_csis_client_module_, GetDesiredSize(_)).WillByDefault(Return(group_size));
5045 
5046   log::info("Connecting first Group with device {}", test_address0);
5047   ConnectCsisDevice(
5048           test_address0, 1 /* conn_id*/,
5049           codec_spec_conf::kLeAudioLocationFrontLeft | codec_spec_conf::kLeAudioLocationFrontRight,
5050           codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id_1, 1 /* rank*/);
5051 
5052   SyncOnMainLoop();
5053 
5054   log::info("Connecting second Group with device {}", test_address1);
5055   ConnectCsisDevice(
5056           test_address1, 2 /* conn_id*/,
5057           codec_spec_conf::kLeAudioLocationFrontLeft | codec_spec_conf::kLeAudioLocationFrontRight,
5058           codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id_2, 1 /* rank*/);
5059   SyncOnMainLoop();
5060   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
5061 
5062   EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, _)).Times(0);
5063   EXPECT_CALL(mock_state_machine_, ConfigureStream(_, _, _, _, _)).Times(0);
5064 
5065   log::info("Group is getting Active");
5066   LeAudioClient::Get()->GroupSetActive(group_id_1);
5067 
5068   SyncOnMainLoop();
5069   Mock::VerifyAndClearExpectations(&mock_state_machine_);
5070 
5071   log::info("Audio HAL opens for Media");
5072 
5073   constexpr int gmcs_ccid = 1;
5074   LeAudioClient::Get()->SetCcidInformation(gmcs_ccid, static_cast<int>(LeAudioContextType::MEDIA));
5075 
5076   types::BidirectionalPair<std::vector<uint8_t>> ccids = {.sink = {gmcs_ccid}, .source = {}};
5077   EXPECT_CALL(mock_state_machine_, StartStream(_, types::LeAudioContextType::MEDIA, _, ccids))
5078           .Times(AtLeast(1));
5079 
5080   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id_1);
5081 
5082   SyncOnMainLoop();
5083   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
5084   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
5085 
5086   log::info("Set group 2 as active one ");
5087   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(1);
5088   EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, _)).Times(0);
5089   EXPECT_CALL(mock_state_machine_,
5090               ConfigureStream(_, types::LeAudioContextType::MEDIA, _, _, false))
5091           .Times(1);
5092 
5093   LeAudioClient::Get()->GroupSetActive(group_id_2);
5094 
5095   SyncOnMainLoop();
5096   Mock::VerifyAndClearExpectations(&mock_state_machine_);
5097 
5098   LocalAudioSourceResume();
5099   SyncOnMainLoop();
5100 }
5101 
TEST_F(UnicastTest,AnotherGroupSetActive_DuringVoip)5102 TEST_F(UnicastTest, AnotherGroupSetActive_DuringVoip) {
5103   const RawAddress test_address0 = GetTestAddress(0);
5104   const RawAddress test_address1 = GetTestAddress(1);
5105   int group_id_1 = 1;
5106   int group_id_2 = 2;
5107   int group_size = 1;
5108 
5109   default_channel_cnt = 2;
5110   default_src_channel_cnt = 1;
5111 
5112   /**
5113    * Scenario:
5114    * 1. Voip is started
5115    * 2. Group 1 is set active - no fast configuration is expected
5116    * 3. Audio HAL resumse the stream and Group 1 is streaming
5117    * 3. Group 2 is set to active - it is expected that stream to Group 1 is stopped and Group 2
5118    * configuration goes to QoS configured
5119    */
5120   // Report working CSIS
5121   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
5122   ON_CALL(mock_csis_client_module_, GetDesiredSize(_)).WillByDefault(Return(group_size));
5123 
5124   log::info("Connecting first Group with device {}", test_address0);
5125   ConnectCsisDevice(
5126           test_address0, 1 /* conn_id*/,
5127           codec_spec_conf::kLeAudioLocationFrontLeft | codec_spec_conf::kLeAudioLocationFrontRight,
5128           codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id_1, 1 /* rank*/);
5129 
5130   SyncOnMainLoop();
5131 
5132   log::info("Connecting second Group with device {}", test_address1);
5133   ConnectCsisDevice(
5134           test_address1, 2 /* conn_id*/,
5135           codec_spec_conf::kLeAudioLocationFrontLeft | codec_spec_conf::kLeAudioLocationFrontRight,
5136           codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id_2, 1 /* rank*/);
5137   SyncOnMainLoop();
5138   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
5139 
5140   EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, _)).Times(0);
5141   EXPECT_CALL(mock_state_machine_, ConfigureStream(_, _, _, _, _)).Times(0);
5142 
5143   log::info("Group is getting Active");
5144   LeAudioClient::Get()->GroupSetActive(group_id_1);
5145 
5146   SyncOnMainLoop();
5147   Mock::VerifyAndClearExpectations(&mock_state_machine_);
5148 
5149   log::info("Audio HAL opens for Converstational");
5150 
5151   // VOIP not using Telecom API has no ccids.
5152   types::BidirectionalPair<std::vector<uint8_t>> ccids = {.sink = {}, .source = {}};
5153   EXPECT_CALL(mock_state_machine_,
5154               StartStream(_, types::LeAudioContextType::CONVERSATIONAL, _, ccids))
5155           .Times(AtLeast(1));
5156 
5157   StartStreaming(AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_CONTENT_TYPE_SPEECH, group_id_1);
5158 
5159   SyncOnMainLoop();
5160   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
5161   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
5162 
5163   log::info("Set group 2 as active one ");
5164   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(1);
5165   EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, _)).Times(0);
5166   EXPECT_CALL(mock_state_machine_, ConfigureStream(_, _, _, _, true)).Times(1);
5167 
5168   LeAudioClient::Get()->GroupSetActive(group_id_2);
5169 
5170   SyncOnMainLoop();
5171   Mock::VerifyAndClearExpectations(&mock_state_machine_);
5172 }
5173 
TEST_F(UnicastTest,GroupSetActive_and_GroupSetInactive_DuringPhoneCall)5174 TEST_F(UnicastTest, GroupSetActive_and_GroupSetInactive_DuringPhoneCall) {
5175   const RawAddress test_address0 = GetTestAddress(0);
5176   int group_id = bluetooth::groups::kGroupUnknown;
5177 
5178   /**
5179    * Scenario:
5180    * 1. Call is started
5181    * 2. Group is set active - it is expected the state machine to be instructed to Configure to Qos
5182    * 3. Group is set to inactive - it is expected that state machine is instructed to stop *
5183    */
5184 
5185   default_channel_cnt = 1;
5186 
5187   SetSampleDatabaseEarbudsValid(
5188           1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
5189           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
5190           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
5191           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
5192   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5193               OnConnectionState(ConnectionState::CONNECTED, test_address0))
5194           .Times(1);
5195   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5196               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
5197           .WillOnce(DoAll(SaveArg<1>(&group_id)));
5198 
5199   ConnectLeAudio(test_address0);
5200   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
5201 
5202   EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, _)).Times(0);
5203   EXPECT_CALL(mock_state_machine_, ConfigureStream(_, _, _, _, true)).Times(1);
5204 
5205   log::info("Call is started and group is getting Active");
5206   LeAudioClient::Get()->SetInCall(true);
5207   LeAudioClient::Get()->GroupSetActive(group_id);
5208 
5209   SyncOnMainLoop();
5210   Mock::VerifyAndClearExpectations(&mock_state_machine_);
5211 
5212   log::info("Group is getting inctive");
5213   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(1);
5214   LeAudioClient::Get()->GroupSetActive(bluetooth::groups::kGroupUnknown);
5215 
5216   SyncOnMainLoop();
5217   Mock::VerifyAndClearExpectations(&mock_state_machine_);
5218 }
5219 
TEST_F(UnicastTest,GroupSetActive_DuringPhoneCall_ThenResume)5220 TEST_F(UnicastTest, GroupSetActive_DuringPhoneCall_ThenResume) {
5221   const RawAddress test_address0 = GetTestAddress(0);
5222   int group_id = bluetooth::groups::kGroupUnknown;
5223 
5224   /**
5225    * Scenario:
5226    * 1. Call is started
5227    * 2. Group is set active - it is expected the state machine to be instructed to Configure to Qos
5228    * 3. Audio Framework callse Resume - expect stream is started.
5229    * 4. Group is set to inactive - it is expected that state machine is instructed to stop *
5230    */
5231 
5232   default_channel_cnt = 1;
5233 
5234   SetSampleDatabaseEarbudsValid(
5235           1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
5236           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
5237           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
5238           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
5239   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5240               OnConnectionState(ConnectionState::CONNECTED, test_address0))
5241           .Times(1);
5242   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5243               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
5244           .WillOnce(DoAll(SaveArg<1>(&group_id)));
5245 
5246   ConnectLeAudio(test_address0);
5247   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
5248 
5249   EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, _)).Times(0);
5250   EXPECT_CALL(mock_state_machine_, ConfigureStream(_, _, _, _, true)).Times(1);
5251 
5252   log::info("Call is started and group is getting Active");
5253   LeAudioClient::Get()->SetInCall(true);
5254   LeAudioClient::Get()->GroupSetActive(group_id);
5255 
5256   SyncOnMainLoop();
5257   Mock::VerifyAndClearExpectations(&mock_state_machine_);
5258 
5259   log::info("AF resumes the stream");
5260   /* Simulate resume and expect StartStream to be called.
5261    * Do not expect confirmation on resume, as this part is not mocked on the state machine
5262    */
5263   EXPECT_CALL(mock_state_machine_, StartStream(_, LeAudioContextType::CONVERSATIONAL, _, _))
5264           .Times(1);
5265   LocalAudioSourceResume(true, false);
5266   SyncOnMainLoop();
5267   Mock::VerifyAndClearExpectations(&mock_state_machine_);
5268 
5269   log::info("Group is getting inactive");
5270   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(1);
5271   LeAudioClient::Get()->GroupSetActive(bluetooth::groups::kGroupUnknown);
5272 
5273   SyncOnMainLoop();
5274   Mock::VerifyAndClearExpectations(&mock_state_machine_);
5275 }
5276 
TEST_F(UnicastTest,ChangeAvailableContextTypeWhenInCodecConfigured)5277 TEST_F(UnicastTest, ChangeAvailableContextTypeWhenInCodecConfigured) {
5278   const RawAddress test_address0 = GetTestAddress(0);
5279   int group_id = bluetooth::groups::kGroupUnknown;
5280 
5281   /**
5282    * In this test we want to make sure that Available context change reach Java
5283    * when group is in Configured state
5284    */
5285 
5286   default_channel_cnt = 1;
5287 
5288   SetSampleDatabaseEarbudsValid(
5289           1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
5290           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
5291           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
5292           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
5293   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5294               OnConnectionState(ConnectionState::CONNECTED, test_address0))
5295           .Times(1);
5296   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5297               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
5298           .WillOnce(DoAll(SaveArg<1>(&group_id)));
5299 
5300   ConnectLeAudio(test_address0);
5301   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
5302 
5303   // Audio sessions are started only when device gets active
5304   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
5305   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
5306   LeAudioClient::Get()->GroupSetActive(group_id);
5307   SyncOnMainLoop();
5308 
5309   EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, _)).Times(1);
5310 
5311   UpdateLocalSinkMetadata(AUDIO_SOURCE_MIC);
5312   LocalAudioSinkResume();
5313 
5314   SyncOnMainLoop();
5315   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
5316   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
5317   Mock::VerifyAndClearExpectations(&mock_state_machine_);
5318 
5319   // Verify Data transfer on local audio sink which is started
5320   constexpr uint8_t cis_count_out = 0;
5321   constexpr uint8_t cis_count_in = 1;
5322   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 0, 40);
5323 
5324   // Remember group to set the state after stopping the stream
5325   ASSERT_NE(0lu, streaming_groups.count(group_id));
5326   auto group = streaming_groups.at(group_id);
5327 
5328   SyncOnMainLoop();
5329   StopStreaming(group_id, true);
5330   SyncOnMainLoop();
5331 
5332   // simulate suspend timeout passed, alarm executing
5333   fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
5334   SyncOnMainLoop();
5335 
5336   // Simulate state Configured
5337   group->SetState(types::AseState::BTA_LE_AUDIO_ASE_STATE_CODEC_CONFIGURED);
5338 
5339   EXPECT_CALL(mock_audio_hal_client_callbacks_, OnAudioConf(_, _, _, _, _));
5340 
5341   /* Check if available context will be sent to Java */
5342   auto sink_available_context = types::kLeAudioContextAllRemoteSinkOnly;
5343   auto source_available_context = types::kLeAudioContextAllRemoteSource;
5344 
5345   InjectAvailableContextTypes(test_address0, 1, sink_available_context, source_available_context);
5346 
5347   SyncOnMainLoop();
5348   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
5349 }
5350 
TEST_F(UnicastTest,TestUpdateConfigurationCallbackWhileStreaming)5351 TEST_F(UnicastTest, TestUpdateConfigurationCallbackWhileStreaming) {
5352   const RawAddress test_address0 = GetTestAddress(0);
5353   int group_id = bluetooth::groups::kGroupUnknown;
5354 
5355   SetSampleDatabaseEarbudsValid(
5356           1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
5357           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
5358           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
5359           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
5360   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5361               OnConnectionState(ConnectionState::CONNECTED, test_address0))
5362           .Times(1);
5363   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5364               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
5365           .WillOnce(DoAll(SaveArg<1>(&group_id)));
5366 
5367   ConnectLeAudio(test_address0);
5368   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
5369 
5370   // Start streaming
5371   LeAudioClient::Get()->GroupSetActive(group_id);
5372   SyncOnMainLoop();
5373 
5374   EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, _)).Times(1);
5375   EXPECT_CALL(mock_audio_hal_client_callbacks_, OnAudioGroupCurrentCodecConf(group_id, _, _))
5376           .Times(1);
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_state_machine_);
5382   SyncOnMainLoop();
5383 
5384   // When metadata update happen, there should be no configuration change
5385   // callback sent
5386   EXPECT_CALL(mock_audio_hal_client_callbacks_, OnAudioGroupCurrentCodecConf(group_id, _, _))
5387           .Times(0);
5388 
5389   EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, _)).Times(1);
5390   UpdateLocalSourceMetadata(AUDIO_USAGE_ALARM, AUDIO_CONTENT_TYPE_UNKNOWN);
5391 
5392   // Inject STREAMING Status from state machine.
5393   auto group = streaming_groups.at(group_id);
5394   do_in_main_thread(base::BindOnce(
5395           [](int group_id,
5396              bluetooth::le_audio::LeAudioGroupStateMachine::Callbacks* state_machine_callbacks,
5397              LeAudioDeviceGroup* /*group*/) {
5398             state_machine_callbacks->StatusReportCb(group_id, GroupStreamStatus::STREAMING);
5399           },
5400           group_id, base::Unretained(this->state_machine_callbacks_), std::move(group)));
5401 
5402   SyncOnMainLoop();
5403   Mock::VerifyAndClearExpectations(&mock_state_machine_);
5404   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
5405 }
5406 
TEST_F(UnicastTest,TestDeactivateWhileStartingStream)5407 TEST_F(UnicastTest, TestDeactivateWhileStartingStream) {
5408   const RawAddress test_address0 = GetTestAddress(0);
5409   int group_id = bluetooth::groups::kGroupUnknown;
5410 
5411   SetSampleDatabaseEarbudsValid(
5412           1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
5413           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
5414           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
5415           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
5416   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5417               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
5418           .WillOnce(DoAll(SaveArg<1>(&group_id)));
5419 
5420   ConnectLeAudio(test_address0);
5421   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
5422 
5423   // Start streaming
5424   LeAudioClient::Get()->GroupSetActive(group_id);
5425   SyncOnMainLoop();
5426   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
5427 
5428   // Deactivate while starting to stream
5429   LeAudioClient::Get()->GroupSetActive(bluetooth::groups::kGroupUnknown);
5430 
5431   // Inject STREAMING Status from state machine.
5432   auto group = streaming_groups.at(group_id);
5433   do_in_main_thread(base::BindOnce(
5434           [](int group_id,
5435              bluetooth::le_audio::LeAudioGroupStateMachine::Callbacks* state_machine_callbacks,
5436              LeAudioDeviceGroup* /*group*/) {
5437             state_machine_callbacks->StatusReportCb(group_id, GroupStreamStatus::STREAMING);
5438           },
5439           group_id, base::Unretained(this->state_machine_callbacks_), std::move(group)));
5440   SyncOnMainLoop();
5441 }
5442 
TEST_F(UnicastTest,RemoveNodeWhileStreaming)5443 TEST_F(UnicastTest, RemoveNodeWhileStreaming) {
5444   const RawAddress test_address0 = GetTestAddress(0);
5445   int group_id = bluetooth::groups::kGroupUnknown;
5446 
5447   SetSampleDatabaseEarbudsValid(
5448           1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
5449           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
5450           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
5451           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
5452   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5453               OnConnectionState(ConnectionState::CONNECTED, test_address0))
5454           .Times(1);
5455   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5456               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
5457           .WillOnce(DoAll(SaveArg<1>(&group_id)));
5458 
5459   ConnectLeAudio(test_address0);
5460   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
5461 
5462   // Start streaming
5463   constexpr uint8_t cis_count_out = 1;
5464   constexpr uint8_t cis_count_in = 0;
5465 
5466   constexpr int gmcs_ccid = 1;
5467   constexpr int gtbs_ccid = 2;
5468 
5469   // Audio sessions are started only when device gets active
5470   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
5471   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
5472   LeAudioClient::Get()->SetCcidInformation(gmcs_ccid, 4 /* Media */);
5473   LeAudioClient::Get()->SetCcidInformation(gtbs_ccid, 2 /* Phone */);
5474   LeAudioClient::Get()->GroupSetActive(group_id);
5475   SyncOnMainLoop();
5476 
5477   types::BidirectionalPair<std::vector<uint8_t>> ccids = {.sink = {gmcs_ccid}, .source = {}};
5478   EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, ccids)).Times(1);
5479 
5480   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
5481 
5482   SyncOnMainLoop();
5483   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
5484   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
5485   Mock::VerifyAndClearExpectations(&mock_state_machine_);
5486   SyncOnMainLoop();
5487 
5488   // Verify Data transfer on one audio source cis
5489   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
5490 
5491   EXPECT_CALL(mock_groups_module_, RemoveDevice(test_address0, group_id)).Times(1);
5492   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(1);
5493   EXPECT_CALL(mock_state_machine_, ProcessHciNotifAclDisconnected(_, _)).Times(1);
5494   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5495               OnGroupNodeStatus(test_address0, group_id, GroupNodeStatus::REMOVED));
5496   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5497               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
5498           .Times(1);
5499 
5500   LeAudioClient::Get()->GroupRemoveNode(group_id, test_address0);
5501 
5502   SyncOnMainLoop();
5503   Mock::VerifyAndClearExpectations(&mock_groups_module_);
5504   Mock::VerifyAndClearExpectations(&mock_state_machine_);
5505   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
5506 }
5507 
TEST_F(UnicastTest,InactiveDeviceOnInternalStateMachineError)5508 TEST_F(UnicastTest, InactiveDeviceOnInternalStateMachineError) {
5509   const RawAddress test_address0 = GetTestAddress(0);
5510   int group_id = bluetooth::groups::kGroupUnknown;
5511 
5512   SetSampleDatabaseEarbudsValid(
5513           1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
5514           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
5515           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
5516           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
5517   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5518               OnConnectionState(ConnectionState::CONNECTED, test_address0))
5519           .Times(1);
5520   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5521               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
5522           .WillOnce(DoAll(SaveArg<1>(&group_id)));
5523 
5524   ConnectLeAudio(test_address0);
5525   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
5526 
5527   // Start streaming
5528   constexpr uint8_t cis_count_out = 1;
5529   constexpr uint8_t cis_count_in = 0;
5530 
5531   constexpr int gmcs_ccid = 1;
5532   constexpr int gtbs_ccid = 2;
5533 
5534   // Audio sessions are started only when device gets active
5535   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
5536   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
5537   LeAudioClient::Get()->SetCcidInformation(gmcs_ccid, 4 /* Media */);
5538   LeAudioClient::Get()->SetCcidInformation(gtbs_ccid, 2 /* Phone */);
5539   LeAudioClient::Get()->GroupSetActive(group_id);
5540   SyncOnMainLoop();
5541 
5542   types::BidirectionalPair<std::vector<uint8_t>> ccids = {.sink = {gmcs_ccid}, .source = {}};
5543   EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, ccids)).Times(1);
5544 
5545   btle_audio_codec_config_t empty_conf{};
5546   btle_audio_codec_config_t output_config = {
5547           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
5548           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_48000HZ,
5549           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
5550           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_2,
5551           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
5552           .octets_per_frame = 120};
5553 
5554   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5555               OnAudioGroupCurrentCodecConf(group_id, empty_conf, output_config))
5556           .Times(1);
5557 
5558   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
5559 
5560   SyncOnMainLoop();
5561   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
5562   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
5563   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
5564   Mock::VerifyAndClearExpectations(&mock_state_machine_);
5565   SyncOnMainLoop();
5566 
5567   // Verify Data transfer on one audio source cis
5568   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
5569 
5570   EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop()).Times(1);
5571   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Stop()).Times(1);
5572 
5573   EXPECT_CALL(mock_audio_hal_client_callbacks_, OnGroupStatus(group_id, GroupStatus::INACTIVE))
5574           .Times(1);
5575 
5576   /* This is internal error of the state machine */
5577   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::RELEASING);
5578 
5579   SyncOnMainLoop();
5580   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
5581   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
5582   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
5583 }
5584 
TEST_F(UnicastTest,GroupingAddTwiceNoRemove)5585 TEST_F(UnicastTest, GroupingAddTwiceNoRemove) {
5586   // Earbud connects without known grouping
5587   uint8_t group_id0 = bluetooth::groups::kGroupUnknown;
5588   const RawAddress test_address0 = GetTestAddress(0);
5589   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true))
5590           .WillOnce(Return())
5591           .RetiresOnSaturation();
5592   ConnectNonCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
5593                        codec_spec_conf::kLeAudioLocationFrontLeft);
5594 
5595   group_id0 = MockDeviceGroups::DeviceGroups::Get()->GetGroupId(test_address0);
5596 
5597   // Earbud connects without known grouping
5598   uint8_t group_id1 = bluetooth::groups::kGroupUnknown;
5599   const RawAddress test_address1 = GetTestAddress(1);
5600   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true))
5601           .WillOnce(Return())
5602           .RetiresOnSaturation();
5603   ConnectNonCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
5604                        codec_spec_conf::kLeAudioLocationFrontRight);
5605 
5606   Mock::VerifyAndClearExpectations(&mock_btif_storage_);
5607 
5608   group_id1 = MockDeviceGroups::DeviceGroups::Get()->GetGroupId(test_address1);
5609   // Verify individual groups
5610   ASSERT_NE(group_id0, bluetooth::groups::kGroupUnknown);
5611   ASSERT_NE(group_id1, bluetooth::groups::kGroupUnknown);
5612   ASSERT_NE(group_id0, group_id1);
5613   ASSERT_EQ(LeAudioClient::Get()->GetGroupDevices(group_id0).size(), 1u);
5614   ASSERT_EQ(LeAudioClient::Get()->GetGroupDevices(group_id1).size(), 1u);
5615 
5616   // Expectations on reassigning second earbud to the first group
5617   int dev1_storage_group = bluetooth::groups::kGroupUnknown;
5618   int dev1_new_group = bluetooth::groups::kGroupUnknown;
5619 
5620   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5621               OnGroupNodeStatus(test_address1, group_id1, GroupNodeStatus::REMOVED))
5622           .Times(AtLeast(1));
5623   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5624               OnGroupNodeStatus(test_address1, _, GroupNodeStatus::ADDED))
5625           .WillRepeatedly(SaveArg<1>(&dev1_new_group));
5626 
5627   // FIXME: We should expect removal with group_id context. No such API exists.
5628   EXPECT_CALL(mock_groups_module_, RemoveDevice(test_address1, group_id1)).Times(AtLeast(1));
5629   EXPECT_CALL(mock_groups_module_, AddDevice(test_address1, _, _)).Times(AnyNumber());
5630   EXPECT_CALL(mock_groups_module_, AddDevice(test_address1, _, group_id0)).Times(1);
5631 
5632   // Regroup device: assign new group without removing it from the first one
5633   LeAudioClient::Get()->GroupAddNode(group_id0, test_address1);
5634   SyncOnMainLoop();
5635   Mock::VerifyAndClearExpectations(&mock_groups_module_);
5636 
5637   dev1_storage_group = MockDeviceGroups::DeviceGroups::Get()->GetGroupId(test_address1);
5638 
5639   // Verify regrouping results
5640   EXPECT_EQ(dev1_new_group, group_id0);
5641   EXPECT_EQ(dev1_new_group, dev1_storage_group);
5642   ASSERT_EQ(LeAudioClient::Get()->GetGroupDevices(group_id1).size(), 0u);
5643   ASSERT_EQ(LeAudioClient::Get()->GetGroupDevices(group_id0).size(), 2u);
5644   std::vector<RawAddress> devs = LeAudioClient::Get()->GetGroupDevices(group_id0);
5645   ASSERT_NE(std::find(devs.begin(), devs.end(), test_address0), devs.end());
5646   ASSERT_NE(std::find(devs.begin(), devs.end(), test_address1), devs.end());
5647 }
5648 
TEST_F(UnicastTest,RemoveTwoEarbudsCsisGrouped)5649 TEST_F(UnicastTest, RemoveTwoEarbudsCsisGrouped) {
5650   uint8_t group_size = 2;
5651   int group_id0 = 2;
5652   int group_id1 = 3;
5653 
5654   // Report working CSIS
5655   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
5656 
5657   // First group - First earbud
5658   const RawAddress test_address0 = GetTestAddress(0);
5659   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
5660   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
5661                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id0, 1 /* rank*/);
5662 
5663   // First group - Second earbud
5664   const RawAddress test_address1 = GetTestAddress(1);
5665   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
5666   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
5667                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id0, 2 /* rank*/,
5668                     true /*connect_through_csis*/);
5669 
5670   // Second group - First earbud
5671   const RawAddress test_address2 = GetTestAddress(2);
5672   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address2, true)).Times(1);
5673   ConnectCsisDevice(test_address2, 3 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
5674                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id1, 1 /* rank*/);
5675 
5676   // Second group - Second earbud
5677   const RawAddress test_address3 = GetTestAddress(3);
5678   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address3, true)).Times(1);
5679   ConnectCsisDevice(test_address3, 4 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
5680                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id1, 2 /* rank*/,
5681                     true /*connect_through_csis*/);
5682 
5683   // First group - verify grouping information
5684   std::vector<RawAddress> group0_devs = LeAudioClient::Get()->GetGroupDevices(group_id0);
5685   ASSERT_NE(std::find(group0_devs.begin(), group0_devs.end(), test_address0), group0_devs.end());
5686   ASSERT_NE(std::find(group0_devs.begin(), group0_devs.end(), test_address1), group0_devs.end());
5687 
5688   // Second group - verify grouping information
5689   std::vector<RawAddress> group1_devs = LeAudioClient::Get()->GetGroupDevices(group_id1);
5690   ASSERT_NE(std::find(group1_devs.begin(), group1_devs.end(), test_address2), group1_devs.end());
5691   ASSERT_NE(std::find(group1_devs.begin(), group1_devs.end(), test_address3), group1_devs.end());
5692   Mock::VerifyAndClearExpectations(&mock_btif_storage_);
5693 
5694   // Expect one of the groups to be dropped and devices to be disconnected
5695   EXPECT_CALL(mock_groups_module_, RemoveDevice(test_address0, group_id0)).Times(1);
5696   EXPECT_CALL(mock_groups_module_, RemoveDevice(test_address1, group_id0)).Times(1);
5697   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5698               OnGroupNodeStatus(test_address0, group_id0, GroupNodeStatus::REMOVED));
5699   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5700               OnGroupNodeStatus(test_address1, group_id0, GroupNodeStatus::REMOVED));
5701   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5702               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
5703           .Times(1);
5704   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5705               OnConnectionState(ConnectionState::DISCONNECTED, test_address1))
5706           .Times(1);
5707 
5708   EXPECT_CALL(mock_btm_interface_, AclDisconnectFromHandle(1, _)).Times(1);
5709   EXPECT_CALL(mock_btm_interface_, AclDisconnectFromHandle(2, _)).Times(1);
5710 
5711   // Expect the other groups to be left as is
5712   EXPECT_CALL(mock_audio_hal_client_callbacks_, OnGroupStatus(group_id1, _)).Times(0);
5713   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5714               OnConnectionState(ConnectionState::DISCONNECTED, test_address2))
5715           .Times(0);
5716   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5717               OnConnectionState(ConnectionState::DISCONNECTED, test_address3))
5718           .Times(0);
5719 
5720   EXPECT_CALL(mock_btm_interface_, AclDisconnectFromHandle(3, _)).Times(0);
5721   EXPECT_CALL(mock_btm_interface_, AclDisconnectFromHandle(4, _)).Times(0);
5722 
5723   do_in_main_thread(base::BindOnce(&LeAudioClient::GroupDestroy,
5724                                    base::Unretained(LeAudioClient::Get()), group_id0));
5725 
5726   SyncOnMainLoop();
5727   Mock::VerifyAndClearExpectations(&mock_btif_storage_);
5728   Mock::VerifyAndClearExpectations(&mock_btm_interface_);
5729 }
5730 
TEST_F(UnicastTest,ConnectAfterRemove)5731 TEST_F(UnicastTest, ConnectAfterRemove) {
5732   const RawAddress test_address0 = GetTestAddress(0);
5733   int group_id = bluetooth::groups::kGroupUnknown;
5734   uint16_t conn_id = 1;
5735 
5736   SetSampleDatabaseEarbudsValid(
5737           conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo,
5738           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
5739           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
5740           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
5741   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5742               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
5743           .Times(1);
5744 
5745   /* RemoveDevice */
5746   do_in_main_thread(base::BindOnce(
5747           [](LeAudioClient* client, const RawAddress& test_address0) {
5748             client->RemoveDevice(test_address0);
5749           },
5750           LeAudioClient::Get(), test_address0));
5751   SyncOnMainLoop();
5752 
5753   ON_CALL(mock_btm_interface_, IsDeviceBonded(_, _)).WillByDefault(DoAll(Return(false)));
5754 
5755   do_in_main_thread(base::BindOnce(&LeAudioClient::Connect, base::Unretained(LeAudioClient::Get()),
5756                                    test_address0));
5757   SyncOnMainLoop();
5758 
5759   Mock::VerifyAndClearExpectations(&mock_btif_storage_);
5760   Mock::VerifyAndClearExpectations(&mock_gatt_queue_);
5761   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
5762 }
5763 
TEST_F(UnicastTest,RemoveDeviceWhenConnected)5764 TEST_F(UnicastTest, RemoveDeviceWhenConnected) {
5765   const RawAddress test_address0 = GetTestAddress(0);
5766   int group_id = bluetooth::groups::kGroupUnknown;
5767   uint16_t conn_id = 1;
5768 
5769   SetSampleDatabaseEarbudsValid(
5770           conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo,
5771           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
5772           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
5773           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
5774   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5775               OnConnectionState(ConnectionState::CONNECTED, test_address0))
5776           .Times(1);
5777   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5778               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
5779           .WillOnce(DoAll(SaveArg<1>(&group_id)));
5780   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
5781   ConnectLeAudio(test_address0);
5782   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
5783 
5784   Mock::VerifyAndClearExpectations(&mock_btif_storage_);
5785   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
5786 
5787   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, false)).Times(1);
5788   EXPECT_CALL(mock_gatt_queue_, Clean(conn_id)).Times(AtLeast(1));
5789   EXPECT_CALL(mock_btm_interface_, AclDisconnectFromHandle(1, _)).Times(1);
5790 
5791   /*
5792    * StopStream will put calls on main_loop so to keep the correct order
5793    * of operations and to avoid races we put the test command on main_loop as
5794    * well.
5795    */
5796   do_in_main_thread(base::BindOnce(
5797           [](LeAudioClient* client, const RawAddress& test_address0) {
5798             client->RemoveDevice(test_address0);
5799           },
5800           LeAudioClient::Get(), test_address0));
5801   SyncOnMainLoop();
5802 
5803   Mock::VerifyAndClearExpectations(&mock_btif_storage_);
5804   Mock::VerifyAndClearExpectations(&mock_gatt_queue_);
5805   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
5806 }
5807 
TEST_F(UnicastTest,RemoveDeviceWhenUserConnecting)5808 TEST_F(UnicastTest, RemoveDeviceWhenUserConnecting) {
5809   const RawAddress test_address0 = GetTestAddress(0);
5810   uint16_t conn_id = 1;
5811 
5812   /* Prepare  mock to not inject connect event so the device can stay in
5813    * CONNECTING state*/
5814   ON_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_DIRECT_CONNECTION, _))
5815           .WillByDefault(DoAll(Return()));
5816 
5817   SetSampleDatabaseEarbudsValid(
5818           conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo,
5819           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
5820           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
5821           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
5822   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5823               OnConnectionState(ConnectionState::CONNECTED, test_address0))
5824           .Times(0);
5825   ConnectLeAudio(test_address0, true, false);
5826 
5827   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
5828 
5829   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, true)).Times(1);
5830   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, false)).Times(1);
5831   EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address0, _, _)).Times(0);
5832 
5833   /*
5834    * StopStream will put calls on main_loop so to keep the correct order
5835    * of operations and to avoid races we put the test command on main_loop as
5836    * well.
5837    */
5838   do_in_main_thread(base::BindOnce(
5839           [](LeAudioClient* client, const RawAddress& test_address0) {
5840             client->RemoveDevice(test_address0);
5841           },
5842           LeAudioClient::Get(), test_address0));
5843 
5844   SyncOnMainLoop();
5845 
5846   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
5847 }
5848 
TEST_F(UnicastTest,RemoveDeviceWhenAutoConnectingWithTargetedAnnouncements)5849 TEST_F(UnicastTest, RemoveDeviceWhenAutoConnectingWithTargetedAnnouncements) {
5850   const RawAddress test_address0 = GetTestAddress(0);
5851   uint16_t conn_id = 1;
5852 
5853   /* Scenario
5854    * 1. Connect device
5855    * 2. Disconnect by remote device -> this shall start Reconnection Using TA
5856    * 3. Remove device
5857    */
5858   SetSampleDatabaseEarbudsValid(
5859           conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo,
5860           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
5861           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
5862           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
5863 
5864   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5865               OnConnectionState(ConnectionState::CONNECTED, test_address0))
5866           .Times(1);
5867   ConnectLeAudio(test_address0, true);
5868 
5869   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
5870   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
5871 
5872   EXPECT_CALL(mock_gatt_interface_,
5873               Open(gatt_if, test_address0, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _))
5874           .Times(1);
5875 
5876   // Inject disconnected event, Reconnect with TA shall start
5877   InjectDisconnectedEvent(conn_id);
5878   SyncOnMainLoop();
5879   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
5880 
5881   // Remove device when being in auto connect state.
5882   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, true)).Times(1);
5883   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, false)).Times(1);
5884   EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address0, _, _)).Times(0);
5885 
5886   do_in_main_thread(base::BindOnce(
5887           [](LeAudioClient* client, const RawAddress& test_address0) {
5888             client->RemoveDevice(test_address0);
5889           },
5890           LeAudioClient::Get(), test_address0));
5891 
5892   SyncOnMainLoop();
5893 
5894   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
5895 }
5896 
TEST_F(UnicastTest,RemoveDeviceWhenAutoConnectingAfterConnectionTimeout)5897 TEST_F(UnicastTest, RemoveDeviceWhenAutoConnectingAfterConnectionTimeout) {
5898   const RawAddress test_address0 = GetTestAddress(0);
5899   uint16_t conn_id = 1;
5900 
5901   /* Scenario
5902    * 1. Connect device
5903    * 2. Disconnect remote device with connection timeout -> this shall start direct connect
5904    * 3. Remove device
5905    */
5906   SetSampleDatabaseEarbudsValid(
5907           conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo,
5908           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
5909           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
5910           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
5911 
5912   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5913               OnConnectionState(ConnectionState::CONNECTED, test_address0))
5914           .Times(1);
5915   ConnectLeAudio(test_address0, true);
5916 
5917   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
5918   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
5919 
5920   // Prepare mock for direct connect and inject connection timeout
5921   ON_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_DIRECT_CONNECTION, _))
5922           .WillByDefault(DoAll(Return()));
5923   EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address0, BTM_BLE_DIRECT_CONNECTION, _))
5924           .Times(1);
5925 
5926   InjectDisconnectedEvent(conn_id, GATT_CONN_TIMEOUT);
5927   SyncOnMainLoop();
5928   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
5929 
5930   // Remove device when being in auto connect state after connection timeout
5931   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, true)).Times(1);
5932   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, false)).Times(1);
5933   EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address0, _, _)).Times(0);
5934 
5935   do_in_main_thread(base::BindOnce(
5936           [](LeAudioClient* client, const RawAddress& test_address0) {
5937             client->RemoveDevice(test_address0);
5938           },
5939           LeAudioClient::Get(), test_address0));
5940 
5941   SyncOnMainLoop();
5942 
5943   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
5944 }
5945 
TEST_F(UnicastTest,RemoveDeviceWhenGettingConnectionReady)5946 TEST_F(UnicastTest, RemoveDeviceWhenGettingConnectionReady) {
5947   const RawAddress test_address0 = GetTestAddress(0);
5948   uint16_t conn_id = 1;
5949 
5950   /* Prepare  mock to not inject Service Search Complete*/
5951   ON_CALL(mock_gatt_interface_, ServiceSearchRequest(_, _)).WillByDefault(DoAll(Return()));
5952 
5953   SetSampleDatabaseEarbudsValid(
5954           conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo,
5955           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
5956           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
5957           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
5958   EXPECT_CALL(mock_audio_hal_client_callbacks_,
5959               OnConnectionState(ConnectionState::CONNECTED, test_address0))
5960           .Times(0);
5961   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, false)).Times(0);
5962   ConnectLeAudio(test_address0);
5963 
5964   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
5965   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
5966 
5967   EXPECT_CALL(mock_gatt_queue_, Clean(conn_id)).Times(AtLeast(1));
5968   EXPECT_CALL(mock_gatt_interface_, Close(conn_id)).Times(1);
5969 
5970   /* Cancel should be called in RemoveDevice */
5971   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, false)).Times(1);
5972   EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address0, _, _)).Times(0);
5973 
5974   /*
5975    * StopStream will put calls on main_loop so to keep the correct order
5976    * of operations and to avoid races we put the test command on main_loop as
5977    * well.
5978    */
5979   do_in_main_thread(base::BindOnce(
5980           [](LeAudioClient* client, const RawAddress& test_address0) {
5981             client->RemoveDevice(test_address0);
5982           },
5983           LeAudioClient::Get(), test_address0));
5984 
5985   SyncOnMainLoop();
5986 
5987   Mock::VerifyAndClearExpectations(&mock_btif_storage_);
5988   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
5989 }
5990 
TEST_F(UnicastTest,DisconnectDeviceWhenConnected)5991 TEST_F(UnicastTest, DisconnectDeviceWhenConnected) {
5992   const RawAddress test_address0 = GetTestAddress(0);
5993   int group_id = bluetooth::groups::kGroupUnknown;
5994   uint16_t conn_id = 1;
5995 
5996   SetSampleDatabaseEarbudsValid(
5997           conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo,
5998           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
5999           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
6000           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
6001   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6002               OnConnectionState(ConnectionState::CONNECTED, test_address0))
6003           .Times(1);
6004   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6005               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
6006           .WillOnce(DoAll(SaveArg<1>(&group_id)));
6007   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
6008   ConnectLeAudio(test_address0);
6009   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
6010 
6011   Mock::VerifyAndClearExpectations(&mock_btif_storage_);
6012   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6013 
6014   /* for Target announcements AutoConnect is always there, until
6015    * device is removed
6016    */
6017   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, false)).Times(0);
6018   EXPECT_CALL(mock_gatt_queue_, Clean(conn_id)).Times(AtLeast(1));
6019   EXPECT_CALL(mock_btm_interface_, AclDisconnectFromHandle(1, _)).Times(1);
6020 
6021   LeAudioClient::Get()->Disconnect(test_address0);
6022   SyncOnMainLoop();
6023 
6024   Mock::VerifyAndClearExpectations(&mock_btif_storage_);
6025   Mock::VerifyAndClearExpectations(&mock_gatt_queue_);
6026   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
6027 }
6028 
TEST_F(UnicastTest,DisconnectDeviceWhenConnecting)6029 TEST_F(UnicastTest, DisconnectDeviceWhenConnecting) {
6030   const RawAddress test_address0 = GetTestAddress(0);
6031   uint16_t conn_id = 1;
6032 
6033   /* Prepare  mock to not inject connect event so the device can stay in
6034    * CONNECTING state*/
6035   ON_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_DIRECT_CONNECTION, _))
6036           .WillByDefault(DoAll(Return()));
6037 
6038   SetSampleDatabaseEarbudsValid(
6039           conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo,
6040           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
6041           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
6042           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
6043   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6044               OnConnectionState(ConnectionState::CONNECTED, test_address0))
6045           .Times(0);
6046   ConnectLeAudio(test_address0, true, false);
6047 
6048   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6049 
6050   /* Prepare on call mock on Close - to not trigger Inject Disconnection, as it
6051    * is done in default mock.
6052    */
6053   ON_CALL(mock_gatt_interface_, Close(_)).WillByDefault(DoAll(Return()));
6054   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, true)).Times(1);
6055   EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address0, _, _)).Times(0);
6056 
6057   LeAudioClient::Get()->Disconnect(test_address0);
6058   SyncOnMainLoop();
6059 
6060   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
6061 }
6062 
TEST_F(UnicastTest,DisconnectDeviceWhenGettingConnectionReady)6063 TEST_F(UnicastTest, DisconnectDeviceWhenGettingConnectionReady) {
6064   const RawAddress test_address0 = GetTestAddress(0);
6065   uint16_t conn_id = global_conn_id;
6066 
6067   /* Prepare  mock to not inject Service Search Complete*/
6068   ON_CALL(mock_gatt_interface_, ServiceSearchRequest(_, _)).WillByDefault(DoAll(Return()));
6069 
6070   SetSampleDatabaseEarbudsValid(
6071           conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo,
6072           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
6073           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
6074           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
6075   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6076               OnConnectionState(ConnectionState::CONNECTED, test_address0))
6077           .Times(0);
6078   ConnectLeAudio(test_address0);
6079 
6080   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6081   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
6082 
6083   /* TA reconnect is enabled in ConnectLeAudio. Make sure this is not removed */
6084   EXPECT_CALL(mock_gatt_queue_, Clean(conn_id)).Times(AtLeast(1));
6085   EXPECT_CALL(mock_gatt_interface_, Close(conn_id)).Times(1);
6086   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, _)).Times(0);
6087   EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address0, _, _)).Times(0);
6088 
6089   LeAudioClient::Get()->Disconnect(test_address0);
6090   SyncOnMainLoop();
6091 
6092   Mock::VerifyAndClearExpectations(&mock_gatt_queue_);
6093   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
6094 }
6095 
TEST_F(UnicastTest,RemoveWhileStreaming)6096 TEST_F(UnicastTest, RemoveWhileStreaming) {
6097   const RawAddress test_address0 = GetTestAddress(0);
6098   int group_id = bluetooth::groups::kGroupUnknown;
6099 
6100   SetSampleDatabaseEarbudsValid(
6101           1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
6102           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
6103           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
6104           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
6105   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6106               OnConnectionState(ConnectionState::CONNECTED, test_address0))
6107           .Times(1);
6108   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6109               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
6110           .WillOnce(DoAll(SaveArg<1>(&group_id)));
6111 
6112   ConnectLeAudio(test_address0);
6113   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
6114 
6115   // Start streaming
6116   constexpr uint8_t cis_count_out = 1;
6117   constexpr uint8_t cis_count_in = 0;
6118 
6119   constexpr int gmcs_ccid = 1;
6120   constexpr int gtbs_ccid = 2;
6121 
6122   // Audio sessions are started only when device gets active
6123   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
6124   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
6125   LeAudioClient::Get()->SetCcidInformation(gmcs_ccid, 4 /* Media */);
6126   LeAudioClient::Get()->SetCcidInformation(gtbs_ccid, 2 /* Phone */);
6127   LeAudioClient::Get()->GroupSetActive(group_id);
6128   SyncOnMainLoop();
6129 
6130   types::BidirectionalPair<std::vector<uint8_t>> ccids = {.sink = {gmcs_ccid}, .source = {}};
6131   EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, ccids)).Times(1);
6132 
6133   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
6134 
6135   SyncOnMainLoop();
6136   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6137   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
6138   Mock::VerifyAndClearExpectations(&mock_state_machine_);
6139   SyncOnMainLoop();
6140 
6141   // Verify Data transfer on one audio source cis
6142   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
6143 
6144   EXPECT_CALL(mock_groups_module_, RemoveDevice(test_address0, group_id)).Times(1);
6145 
6146   LeAudioDeviceGroup* group = nullptr;
6147   EXPECT_CALL(mock_state_machine_, ProcessHciNotifAclDisconnected(_, _))
6148           .WillOnce(DoAll(SaveArg<0>(&group)));
6149   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6150               OnGroupNodeStatus(test_address0, group_id, GroupNodeStatus::REMOVED));
6151 
6152   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6153               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
6154           .Times(1);
6155 
6156   /*
6157    * StopStream will put calls on main_loop so to keep the correct order
6158    * of operations and to avoid races we put the test command on main_loop as
6159    * well.
6160    */
6161   do_in_main_thread(base::BindOnce(
6162           [](LeAudioClient* client, const RawAddress& test_address0) {
6163             client->RemoveDevice(test_address0);
6164           },
6165           LeAudioClient::Get(), test_address0));
6166 
6167   SyncOnMainLoop();
6168   Mock::VerifyAndClearExpectations(&mock_groups_module_);
6169   Mock::VerifyAndClearExpectations(&mock_state_machine_);
6170   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6171 
6172   ASSERT_EQ(group, nullptr);
6173 }
6174 
TEST_F(UnicastTest,DisconnecteWhileAlmostStreaming)6175 TEST_F(UnicastTest, DisconnecteWhileAlmostStreaming) {
6176   const RawAddress test_address0 = GetTestAddress(0);
6177   int group_id = bluetooth::groups::kGroupUnknown;
6178 
6179   SetSampleDatabaseEarbudsValid(
6180           1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
6181           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
6182           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
6183           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
6184   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6185               OnConnectionState(ConnectionState::CONNECTED, test_address0))
6186           .Times(1);
6187   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6188               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
6189           .WillOnce(DoAll(SaveArg<1>(&group_id)));
6190 
6191   ConnectLeAudio(test_address0);
6192   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
6193 
6194   constexpr int gmcs_ccid = 1;
6195   constexpr int gtbs_ccid = 2;
6196 
6197   // Audio sessions are started only when device gets active
6198   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
6199   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
6200   LeAudioClient::Get()->SetCcidInformation(gmcs_ccid, 4 /* Media */);
6201   LeAudioClient::Get()->SetCcidInformation(gtbs_ccid, 2 /* Phone */);
6202   LeAudioClient::Get()->GroupSetActive(group_id);
6203   SyncOnMainLoop();
6204 
6205   types::BidirectionalPair<std::vector<uint8_t>> ccids = {.sink = {gmcs_ccid}, .source = {}};
6206   EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, ccids)).Times(1);
6207 
6208   /* We want here to CIS be established but device not being yet in streaming
6209    * state
6210    */
6211   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
6212 
6213   SyncOnMainLoop();
6214   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6215   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
6216   Mock::VerifyAndClearExpectations(&mock_state_machine_);
6217   SyncOnMainLoop();
6218 
6219   /* This is test code, which will change the group state to the one which
6220    * is required by test
6221    */
6222   ASSERT_NE(0lu, streaming_groups.count(group_id));
6223   auto group_inject = streaming_groups.at(group_id);
6224   group_inject->SetState(types::AseState::BTA_LE_AUDIO_ASE_STATE_ENABLING);
6225 
6226   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(1);
6227 
6228   LeAudioDeviceGroup* group = nullptr;
6229   EXPECT_CALL(mock_state_machine_, ProcessHciNotifAclDisconnected(_, _))
6230           .WillOnce(DoAll(SaveArg<0>(&group)));
6231 
6232   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6233               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
6234           .Times(1);
6235 
6236   /*
6237    * StopStream will put calls on main_loop so to keep the correct order
6238    * of operations and to avoid races we put the test command on main_loop as
6239    * well.
6240    */
6241   do_in_main_thread(
6242           base::BindOnce([](LeAudioClient* client,
6243                             const RawAddress& test_address0) { client->Disconnect(test_address0); },
6244                          LeAudioClient::Get(), test_address0));
6245 
6246   SyncOnMainLoop();
6247   Mock::VerifyAndClearExpectations(&mock_groups_module_);
6248   Mock::VerifyAndClearExpectations(&mock_state_machine_);
6249   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6250 
6251   ASSERT_EQ(group->GetState(), types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE);
6252 }
6253 
TEST_F(UnicastTest,DisconnecteWhileAlmostStreaming_twoDevices)6254 TEST_F(UnicastTest, DisconnecteWhileAlmostStreaming_twoDevices) {
6255   const RawAddress test_address0 = GetTestAddress(0);
6256   const RawAddress test_address1 = GetTestAddress(1);
6257   int group_id = 5;
6258 
6259   TestSetupRemoteDevices(group_id);
6260   SyncOnMainLoop();
6261 
6262   EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, _)).Times(1);
6263 
6264   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
6265 
6266   SyncOnMainLoop();
6267   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6268   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
6269   Mock::VerifyAndClearExpectations(&mock_state_machine_);
6270   SyncOnMainLoop();
6271 
6272   ASSERT_NE(0lu, streaming_groups.count(group_id));
6273   auto group_inject = streaming_groups.at(group_id);
6274 
6275   // This shall be called once only when first device from the group is disconnecting.
6276   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(1);
6277 
6278   EXPECT_CALL(mock_audio_hal_client_callbacks_, OnConnectionState(ConnectionState::DISCONNECTED, _))
6279           .Times(0);
6280 
6281   // Do not got to IDLE state imidiatelly.
6282   stay_at_releasing_stop_stream = true;
6283 
6284   log::info("First of all disconnect: {}", test_address0);
6285   TriggerDisconnectionFromApp(test_address0);
6286   SyncOnMainLoop();
6287 
6288   log::info("Secondly disconnect: {}", test_address1);
6289   TriggerDisconnectionFromApp(test_address1);
6290   SyncOnMainLoop();
6291 
6292   Mock::VerifyAndClearExpectations(&mock_state_machine_);
6293   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6294 
6295   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6296               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
6297           .Times(1);
6298   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6299               OnConnectionState(ConnectionState::DISCONNECTED, test_address1))
6300           .Times(1);
6301 
6302   do_in_main_thread(base::BindOnce(
6303           [](bluetooth::le_audio::LeAudioGroupStateMachine::Callbacks* cb, int group_id) {
6304             cb->StatusReportCb(group_id, GroupStreamStatus::IDLE);
6305           },
6306           state_machine_callbacks_, group_id));
6307   SyncOnMainLoop();
6308   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6309 }
6310 
TEST_F(UnicastTest,EarbudsTwsStyleStreaming)6311 TEST_F(UnicastTest, EarbudsTwsStyleStreaming) {
6312   const RawAddress test_address0 = GetTestAddress(0);
6313   int group_id = bluetooth::groups::kGroupUnknown;
6314 
6315   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
6316                                 codec_spec_conf::kLeAudioLocationStereo, 0x01, 0x01,
6317                                 codec_spec_caps::kLeAudioSamplingFreq16000Hz, false /*add_csis*/,
6318                                 true /*add_cas*/, true /*add_pacs*/, 2 /*add_asc_cnt*/,
6319                                 1 /*set_size*/, 0 /*rank*/);
6320   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6321               OnConnectionState(ConnectionState::CONNECTED, test_address0))
6322           .Times(1);
6323   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6324               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
6325           .WillOnce(DoAll(SaveArg<1>(&group_id)));
6326 
6327   log::info("Connect device");
6328   ConnectLeAudio(test_address0);
6329   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
6330 
6331   // Expected CIS count on streaming
6332   uint8_t cis_count_out = 2;
6333   uint8_t cis_count_in = 0;
6334 
6335   log::info("Group is getting Active");
6336   // Audio sessions are started only when device gets active
6337   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
6338   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
6339   LeAudioClient::Get()->GroupSetActive(group_id);
6340   SyncOnMainLoop();
6341 
6342   log::info("Start stream");
6343   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
6344 
6345   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6346   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
6347   SyncOnMainLoop();
6348 
6349   log::info("Verify Data transfer on one audio source cis");
6350   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
6351 
6352   log::info("Suspend");
6353   EXPECT_CALL(mock_state_machine_, SuspendStream(_)).Times(1);
6354   LeAudioClient::Get()->GroupSuspend(group_id);
6355   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6356   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
6357 
6358   log::info("Resume");
6359   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
6360   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6361   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
6362 
6363   log::info("Stop");
6364   StopStreaming(group_id);
6365   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6366 
6367   // Release
6368   EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop()).Times(1);
6369   EXPECT_CALL(*mock_codec_manager_,
6370               UpdateActiveUnicastAudioHalClient(mock_le_audio_source_hal_client_,
6371                                                 mock_le_audio_sink_hal_client_, false))
6372           .Times(1);
6373 
6374   EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(1);
6375   EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(1);
6376   LeAudioClient::Get()->GroupSetActive(bluetooth::groups::kGroupUnknown);
6377   SyncOnMainLoop();
6378   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
6379   Mock::VerifyAndClearExpectations(mock_codec_manager_);
6380 }
6381 
TEST_F(UnicastTest,SpeakerFailedConversationalStreaming)6382 TEST_F(UnicastTest, SpeakerFailedConversationalStreaming) {
6383   const RawAddress test_address0 = GetTestAddress(0);
6384   int group_id = bluetooth::groups::kGroupUnknown;
6385 
6386   available_src_context_types_ = 0;
6387   supported_src_context_types_ =
6388           available_src_context_types_ |
6389           types::AudioContexts(types::LeAudioContextType::UNSPECIFIED).value();
6390   available_snk_context_types_ = 0x0004;
6391   supported_snk_context_types_ =
6392           available_snk_context_types_ |
6393           types::AudioContexts(types::LeAudioContextType::UNSPECIFIED).value();
6394 
6395   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo, 0,
6396                                 default_channel_cnt, default_channel_cnt, 0x0004,
6397                                 /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/,
6398                                 true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
6399                                 0 /*rank*/);
6400   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6401               OnConnectionState(ConnectionState::CONNECTED, test_address0))
6402           .Times(1);
6403   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6404               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
6405           .WillOnce(DoAll(SaveArg<1>(&group_id)));
6406 
6407   ConnectLeAudio(test_address0);
6408   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
6409 
6410   // Audio sessions are started only when device gets active
6411   LeAudioClient::Get()->GroupSetActive(group_id);
6412   SyncOnMainLoop();
6413 
6414   /* Nothing to do - expect no crash */
6415 }
6416 
TEST_F(UnicastTest,SpeakerStreaming)6417 TEST_F(UnicastTest, SpeakerStreaming) {
6418   const RawAddress test_address0 = GetTestAddress(0);
6419   int group_id = bluetooth::groups::kGroupUnknown;
6420 
6421   SetSampleDatabaseEarbudsValid(
6422           1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
6423           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
6424           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
6425           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
6426   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6427               OnConnectionState(ConnectionState::CONNECTED, test_address0))
6428           .Times(1);
6429   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6430               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
6431           .WillOnce(DoAll(SaveArg<1>(&group_id)));
6432 
6433   ConnectLeAudio(test_address0);
6434   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
6435 
6436   // Start streaming
6437   uint8_t cis_count_out = 1;
6438   uint8_t cis_count_in = 0;
6439 
6440   // Audio sessions are started only when device gets active
6441   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
6442   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
6443   LeAudioClient::Get()->GroupSetActive(group_id);
6444   SyncOnMainLoop();
6445 
6446   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
6447 
6448   SyncOnMainLoop();
6449   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6450   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
6451 
6452   // Verify Data transfer on one audio source cis
6453   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
6454 
6455   // Suspend
6456   /*TODO Need a way to verify STOP */
6457   LeAudioClient::Get()->GroupSuspend(group_id);
6458   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6459   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
6460 
6461   // Resume
6462   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
6463   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6464   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
6465 
6466   // Stop
6467   StopStreaming(group_id);
6468   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6469 
6470   // Release
6471   EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop()).Times(1);
6472 
6473   EXPECT_CALL(*mock_codec_manager_,
6474               UpdateActiveUnicastAudioHalClient(mock_le_audio_source_hal_client_,
6475                                                 mock_le_audio_sink_hal_client_, false))
6476           .Times(1);
6477 
6478   EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(1);
6479   EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(1);
6480   LeAudioClient::Get()->GroupSetActive(bluetooth::groups::kGroupUnknown);
6481   SyncOnMainLoop();
6482   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
6483   Mock::VerifyAndClearExpectations(mock_codec_manager_);
6484 }
6485 
TEST_F(UnicastTest,SpeakerStreamingNonDefault)6486 TEST_F(UnicastTest, SpeakerStreamingNonDefault) {
6487   const RawAddress test_address0 = GetTestAddress(0);
6488   int group_id = bluetooth::groups::kGroupUnknown;
6489 
6490   /**
6491    * Scenario test steps
6492    * 1. Set group active and stream VOICEASSISTANT
6493    * 2. Suspend group and resume with VOICEASSISTANT
6494    * 3. Stop Stream and make group inactive
6495    * 4. Start stream without setting metadata.
6496    * 5. Verify that UNSPECIFIED context type is used.
6497    */
6498 
6499   available_snk_context_types_ =
6500           (types::LeAudioContextType::VOICEASSISTANTS | types::LeAudioContextType::MEDIA |
6501            types::LeAudioContextType::UNSPECIFIED)
6502                   .value();
6503   supported_snk_context_types_ = available_snk_context_types_;
6504 
6505   SetSampleDatabaseEarbudsValid(
6506           1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
6507           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
6508           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
6509           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
6510   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6511               OnConnectionState(ConnectionState::CONNECTED, test_address0))
6512           .Times(1);
6513   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6514               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
6515           .WillOnce(DoAll(SaveArg<1>(&group_id)));
6516 
6517   ConnectLeAudio(test_address0);
6518   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
6519 
6520   // Start streaming
6521   uint8_t cis_count_out = 1;
6522   uint8_t cis_count_in = 0;
6523 
6524   // Audio sessions are started only when device gets active
6525   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
6526   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
6527   LeAudioClient::Get()->GroupSetActive(group_id);
6528   SyncOnMainLoop();
6529 
6530   StartStreaming(AUDIO_USAGE_ASSISTANT, AUDIO_CONTENT_TYPE_UNKNOWN, group_id);
6531 
6532   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6533   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
6534   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
6535   SyncOnMainLoop();
6536 
6537   // Verify Data transfer on one audio source cis
6538   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
6539 
6540   // Suspend
6541   /*TODO Need a way to verify STOP */
6542   LeAudioClient::Get()->GroupSuspend(group_id);
6543   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6544   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
6545 
6546   // Resume
6547   StartStreaming(AUDIO_USAGE_ASSISTANT, AUDIO_CONTENT_TYPE_UNKNOWN, group_id);
6548   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6549   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
6550 
6551   // Stop
6552   StopStreaming(group_id);
6553   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6554 
6555   // Release
6556   EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop()).Times(1);
6557   EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(1);
6558   EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(1);
6559   LeAudioClient::Get()->GroupSetActive(bluetooth::groups::kGroupUnknown);
6560   SyncOnMainLoop();
6561   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
6562 
6563   /* When session is closed, the hal client mocks are freed - get new ones */
6564   SetUpMockAudioHal();
6565   /* Expect the previous release to clear the old audio session metadata */
6566   LeAudioClient::Get()->GroupSetActive(group_id);
6567   SyncOnMainLoop();
6568   EXPECT_CALL(mock_state_machine_, StartStream(_, types::LeAudioContextType::VOICEASSISTANTS, _, _))
6569           .Times(0);
6570   EXPECT_CALL(mock_state_machine_, StartStream(_, kLeAudioDefaultConfigurationContext, _, _))
6571           .Times(1);
6572   LocalAudioSourceResume();
6573 }
6574 
TEST_F(UnicastTest,TestUnidirectionalGameAndLiveRecording)6575 TEST_F(UnicastTest, TestUnidirectionalGameAndLiveRecording) {
6576   const RawAddress test_address0 = GetTestAddress(0);
6577   int group_id = bluetooth::groups::kGroupUnknown;
6578 
6579   /**
6580    * Scenario test steps
6581    * 1. Configure group to support GAME only on SINK
6582    * 2. Configure group to support LIVE
6583    * 3. Start recording with LIVE
6584    * 4. Update context type with GAME
6585    * 5. Verify that Configuration did not changed.
6586    */
6587 
6588   available_snk_context_types_ =
6589           (types::LeAudioContextType::GAME | types::LeAudioContextType::MEDIA |
6590            types::LeAudioContextType::UNSPECIFIED | types::LeAudioContextType::LIVE)
6591                   .value();
6592   supported_snk_context_types_ = available_snk_context_types_;
6593 
6594   available_src_context_types_ =
6595           (types::LeAudioContextType::LIVE | types::LeAudioContextType::UNSPECIFIED).value();
6596   supported_src_context_types_ = available_src_context_types_;
6597 
6598   default_channel_cnt = 1;
6599 
6600   SetSampleDatabaseEarbudsValid(
6601           1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
6602           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
6603           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
6604           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
6605   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6606               OnConnectionState(ConnectionState::CONNECTED, test_address0))
6607           .Times(1);
6608   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6609               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
6610           .WillOnce(DoAll(SaveArg<1>(&group_id)));
6611 
6612   types::BidirectionalPair<types::AudioContexts> metadata_contexts = {
6613           .sink = types::AudioContexts(types::LeAudioContextType::LIVE),
6614           .source = types::AudioContexts(types::LeAudioContextType::LIVE)};
6615   EXPECT_CALL(mock_state_machine_,
6616               StartStream(_, types::LeAudioContextType::LIVE, metadata_contexts, _))
6617           .Times(1);
6618 
6619   log::info("Connecting LeAudio to {}", test_address0);
6620   ConnectLeAudio(test_address0);
6621   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
6622 
6623   // Audio sessions are started only when device gets active
6624   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
6625   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
6626 
6627   EXPECT_CALL(*mock_codec_manager_,
6628               UpdateActiveUnicastAudioHalClient(mock_le_audio_source_hal_client_,
6629                                                 mock_le_audio_sink_hal_client_, true))
6630           .Times(1);
6631 
6632   LeAudioClient::Get()->GroupSetActive(group_id);
6633   SyncOnMainLoop();
6634 
6635   UpdateLocalSinkMetadata(AUDIO_SOURCE_MIC);
6636   LocalAudioSinkResume();
6637   SyncOnMainLoop();
6638 
6639   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6640   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
6641   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
6642   Mock::VerifyAndClearExpectations(mock_codec_manager_);
6643   Mock::VerifyAndClearExpectations(&mock_state_machine_);
6644   SyncOnMainLoop();
6645 
6646   // We do expect only unidirectional CIS
6647   uint8_t cis_count_out = 0;
6648   uint8_t cis_count_in = 1;
6649 
6650   // Verify Data transfer on one local audio source cis
6651   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 0, 40);
6652   SyncOnMainLoop();
6653 
6654   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(0);
6655   UpdateLocalSourceMetadata(AUDIO_USAGE_GAME, AUDIO_CONTENT_TYPE_UNKNOWN);
6656   LocalAudioSourceResume();
6657   SyncOnMainLoop();
6658   Mock::VerifyAndClearExpectations(&mock_state_machine_);
6659 }
6660 
TEST_F(UnicastTest,TestUnidirectionalGameAndLiveRecordingMicOnlyDev)6661 TEST_F(UnicastTest, TestUnidirectionalGameAndLiveRecordingMicOnlyDev) {
6662   const RawAddress test_address0 = GetTestAddress(0);
6663   int group_id = bluetooth::groups::kGroupUnknown;
6664 
6665   /**
6666    * Scenario test steps
6667    * 1. Configure group to support GAME | LIVE | CONVERSATIONAL | VOICEASSISTANTS only on Source
6668    * 2. Start a GAME
6669    * 3. Start recording during the GAME
6670    */
6671 
6672   // No sink at all
6673   available_snk_context_types_ = 0;
6674   supported_snk_context_types_ = 0;
6675 
6676   // Source available for
6677   available_src_context_types_ =
6678           (types::LeAudioContextType::CONVERSATIONAL | types::LeAudioContextType::GAME |
6679            types::LeAudioContextType::LIVE | types::LeAudioContextType::VOICEASSISTANTS |
6680            types::LeAudioContextType::UNSPECIFIED)
6681                   .value();
6682   supported_src_context_types_ = available_src_context_types_;
6683 
6684   // Setup a single mic-only device
6685   empty_sink_pack_ = true;
6686   default_channel_cnt = 1;
6687   SampleDatabaseParameters db_params{
6688           .conn_id = 1,
6689           .addr = test_address0,
6690           .sink_audio_allocation = std::nullopt,
6691           .source_audio_allocation = codec_spec_conf::kLeAudioLocationMonoAudio,
6692           .sink_channel_cnt = 0,
6693           .source_channel_cnt = default_channel_cnt,
6694           .sample_freq_mask = le_audio::codec_spec_caps::kLeAudioSamplingFreq32000Hz,
6695           .add_csis = false,
6696           .add_cas = false,
6697           .add_pacs = true,
6698           .add_ascs_cnt = 1,
6699           .set_size = 0,
6700           .rank = 0,
6701           .gatt_status = GATT_SUCCESS,
6702           .max_supported_codec_frames_per_sdu = 1,
6703   };
6704   SetSampleDatabaseEarbudsValid(db_params);
6705 
6706   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6707               OnConnectionState(ConnectionState::CONNECTED, test_address0))
6708           .Times(1);
6709   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6710               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
6711           .WillOnce(DoAll(SaveArg<1>(&group_id)));
6712 
6713   types::BidirectionalPair<types::AudioContexts> expected_metadata_contexts = {
6714           .sink = types::AudioContexts(),
6715           .source = types::AudioContexts(types::LeAudioContextType::GAME)};
6716   EXPECT_CALL(mock_state_machine_,
6717               StartStream(_, types::LeAudioContextType::GAME, expected_metadata_contexts, _))
6718           .Times(1);
6719 
6720   log::info("Connecting LeAudio to {}", test_address0);
6721   ConnectLeAudio(test_address0);
6722   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
6723 
6724   // Both audio sessions are always started to monitor the metadata (even for mic only devices)
6725   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
6726   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
6727 
6728   EXPECT_CALL(*mock_codec_manager_,
6729               UpdateActiveUnicastAudioHalClient(mock_le_audio_source_hal_client_,
6730                                                 mock_le_audio_sink_hal_client_, true))
6731           .Times(1);
6732 
6733   LeAudioClient::Get()->GroupSetActive(group_id);
6734   SyncOnMainLoop();
6735 
6736   // Configure a bidirectional GAME scenario (on a mic-only device)
6737   UpdateLocalSourceMetadata(AUDIO_USAGE_GAME, AUDIO_CONTENT_TYPE_UNKNOWN);
6738   UpdateLocalSinkMetadata(AUDIO_SOURCE_MIC);
6739   LocalAudioSinkResume();
6740   SyncOnMainLoop();
6741 
6742   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6743   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
6744   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
6745   Mock::VerifyAndClearExpectations(mock_codec_manager_);
6746   Mock::VerifyAndClearExpectations(&mock_state_machine_);
6747   SyncOnMainLoop();
6748 
6749   // We do expect only unidirectional CIS
6750   uint8_t cis_count_out = 0;
6751   uint8_t cis_count_in = 1;
6752 
6753   // Verify Data transfer on one local audio sink
6754   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 0, 40);
6755   SyncOnMainLoop();
6756 
6757   // Expect no reconfiguration triggered by the GAME updates
6758   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(0);
6759   UpdateLocalSourceMetadata(AUDIO_USAGE_GAME, AUDIO_CONTENT_TYPE_UNKNOWN);
6760   LocalAudioSinkSuspend();
6761   SyncOnMainLoop();
6762   Mock::VerifyAndClearExpectations(&mock_state_machine_);
6763 }
6764 
TEST_F(UnicastTest,TestUnidirectionalVoiceAssistant_Sink)6765 TEST_F(UnicastTest, TestUnidirectionalVoiceAssistant_Sink) {
6766   const RawAddress test_address0 = GetTestAddress(0);
6767   int group_id = bluetooth::groups::kGroupUnknown;
6768 
6769   /**
6770    * Scenario test steps
6771    * 1. Configure group to support VOICEASSISTANT only on SINK
6772    * 2. Start stream
6773    * 5. Verify that Unidirectional VOICEASSISTANT has been created
6774    */
6775 
6776   available_snk_context_types_ =
6777           (types::LeAudioContextType::VOICEASSISTANTS | types::LeAudioContextType::MEDIA |
6778            types::LeAudioContextType::UNSPECIFIED)
6779                   .value();
6780   supported_snk_context_types_ = available_snk_context_types_;
6781 
6782   available_src_context_types_ =
6783           (types::LeAudioContextType::LIVE | types::LeAudioContextType::UNSPECIFIED).value();
6784   supported_src_context_types_ = available_src_context_types_;
6785 
6786   SetSampleDatabaseEarbudsValid(
6787           1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
6788           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
6789           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
6790           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
6791   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6792               OnConnectionState(ConnectionState::CONNECTED, test_address0))
6793           .Times(1);
6794   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6795               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
6796           .WillOnce(DoAll(SaveArg<1>(&group_id)));
6797 
6798   types::BidirectionalPair<types::AudioContexts> metadata_contexts = {
6799           .sink = types::AudioContexts(types::LeAudioContextType::VOICEASSISTANTS),
6800           .source = types::AudioContexts()};
6801   EXPECT_CALL(mock_state_machine_,
6802               StartStream(_, types::LeAudioContextType::VOICEASSISTANTS, metadata_contexts, _))
6803           .Times(1);
6804 
6805   log::info("Connecting LeAudio to {}", test_address0);
6806   ConnectLeAudio(test_address0);
6807   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
6808 
6809   // We do expect only unidirectional CIS
6810   uint8_t cis_count_out = 1;
6811   uint8_t cis_count_in = 0;
6812 
6813   // Audio sessions are started only when device gets active
6814   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
6815   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
6816 
6817   EXPECT_CALL(*mock_codec_manager_,
6818               UpdateActiveUnicastAudioHalClient(mock_le_audio_source_hal_client_,
6819                                                 mock_le_audio_sink_hal_client_, true))
6820           .Times(1);
6821 
6822   LeAudioClient::Get()->GroupSetActive(group_id);
6823   SyncOnMainLoop();
6824 
6825   StartStreaming(AUDIO_USAGE_ASSISTANT, AUDIO_CONTENT_TYPE_UNKNOWN, group_id);
6826 
6827   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6828   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
6829   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
6830   Mock::VerifyAndClearExpectations(mock_codec_manager_);
6831   SyncOnMainLoop();
6832 
6833   // Verify Data transfer on one local audio source cis
6834   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
6835   SyncOnMainLoop();
6836 }
6837 
TEST_F(UnicastTest,TestUnidirectionalVoiceAssistant_Source)6838 TEST_F(UnicastTest, TestUnidirectionalVoiceAssistant_Source) {
6839   const RawAddress test_address0 = GetTestAddress(0);
6840   int group_id = bluetooth::groups::kGroupUnknown;
6841 
6842   /**
6843    * Scenario test steps
6844    * 1. Configure group to support VOICEASSISTANT only on SOURCE
6845    * 2. Start stream
6846    * 5. Verify that uni-direction VOICEASSISTANT has been created
6847    */
6848 
6849   available_snk_context_types_ =
6850           (types::LeAudioContextType::MEDIA | types::LeAudioContextType::UNSPECIFIED).value();
6851   supported_snk_context_types_ = available_snk_context_types_;
6852 
6853   available_src_context_types_ =
6854           (types::LeAudioContextType::VOICEASSISTANTS | types::LeAudioContextType::LIVE |
6855            types::LeAudioContextType::UNSPECIFIED)
6856                   .value();
6857   supported_src_context_types_ = available_src_context_types_;
6858 
6859   SetSampleDatabaseEarbudsValid(
6860           1, test_address0, codec_spec_conf::kLeAudioLocationFrontLeftOfCenter,
6861           codec_spec_conf::kLeAudioLocationFrontLeftOfCenter, default_channel_cnt,
6862           default_channel_cnt, 0x0004,
6863           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
6864           default_ase_cnt /*add_ascs_cnt*/, 2 /*set_size*/, 1 /*rank*/);
6865   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6866               OnConnectionState(ConnectionState::CONNECTED, test_address0))
6867           .Times(1);
6868   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6869               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
6870           .WillOnce(DoAll(SaveArg<1>(&group_id)));
6871 
6872   types::BidirectionalPair<types::AudioContexts> metadata_contexts = {
6873           .sink = types::AudioContexts(),
6874           .source = types::AudioContexts(types::LeAudioContextType::VOICEASSISTANTS)};
6875   EXPECT_CALL(mock_state_machine_,
6876               StartStream(_, types::LeAudioContextType::VOICEASSISTANTS, metadata_contexts, _))
6877           .Times(1);
6878 
6879   log::info("Connecting LeAudio device {}", test_address0);
6880 
6881   ConnectLeAudio(test_address0);
6882   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
6883 
6884   // Expected only unidirectional CIS
6885   uint8_t cis_count_out = 0;
6886   uint8_t cis_count_in = 1;
6887 
6888   // Audio sessions are started only when device gets active
6889   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
6890   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
6891   LeAudioClient::Get()->GroupSetActive(group_id);
6892   SyncOnMainLoop();
6893 
6894   UpdateLocalSinkMetadata(AUDIO_SOURCE_VOICE_RECOGNITION);
6895   LocalAudioSinkResume();
6896 
6897   // Verify Data transfer on one local audio source cis
6898   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
6899 
6900   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6901   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
6902   SyncOnMainLoop();
6903 }
6904 
TEST_F(UnicastTest,SpeakerStreamingAutonomousRelease)6905 TEST_F(UnicastTest, SpeakerStreamingAutonomousRelease) {
6906   const RawAddress test_address0 = GetTestAddress(0);
6907   int group_id = bluetooth::groups::kGroupUnknown;
6908 
6909   SetSampleDatabaseEarbudsValid(
6910           1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
6911           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
6912           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
6913           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
6914   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6915               OnConnectionState(ConnectionState::CONNECTED, test_address0))
6916           .Times(1);
6917   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6918               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
6919           .WillOnce(DoAll(SaveArg<1>(&group_id)));
6920 
6921   ConnectLeAudio(test_address0);
6922   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
6923 
6924   // Start streaming
6925   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
6926   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
6927   LeAudioClient::Get()->GroupSetActive(group_id);
6928   SyncOnMainLoop();
6929 
6930   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
6931 
6932   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6933   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
6934   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
6935   SyncOnMainLoop();
6936 
6937   // Verify Data transfer on one audio source cis
6938   TestAudioDataTransfer(group_id, 1 /* cis_count_out */, 0 /* cis_count_in */, 1920);
6939 
6940   EXPECT_CALL(mock_audio_hal_client_callbacks_, OnGroupStatus(group_id, GroupStatus::INACTIVE))
6941           .Times(1);
6942   EXPECT_CALL(mock_audio_hal_client_callbacks_,
6943               OnGroupStreamStatus(group_id, GroupStreamStatus::IDLE))
6944           .Times(1);
6945 
6946   // Inject the IDLE state as if an autonomous release happened
6947   ASSERT_NE(0lu, streaming_groups.count(group_id));
6948   auto group = streaming_groups.at(group_id);
6949   ASSERT_NE(group, nullptr);
6950   for (LeAudioDevice* device = group->GetFirstDevice(); device != nullptr;
6951        device = group->GetNextDevice(device)) {
6952     for (auto& ase : device->ases_) {
6953       ase.cis_state = types::CisState::IDLE;
6954       ase.data_path_state = types::DataPathState::IDLE;
6955       ase.state = types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE;
6956       InjectCisDisconnected(group_id, ase.cis_conn_hdl);
6957     }
6958   }
6959   // Verify no Data transfer after the autonomous release
6960   TestAudioDataTransfer(group_id, 0 /* cis_count_out */, 0 /* cis_count_in */, 1920);
6961 
6962   // Inject Releasing
6963   state_machine_callbacks_->StatusReportCb(group->group_id_,
6964                                            GroupStreamStatus::RELEASING_AUTONOMOUS);
6965   SyncOnMainLoop();
6966   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
6967 }
6968 
TEST_F(UnicastTest,TwoEarbudsStreaming)6969 TEST_F(UnicastTest, TwoEarbudsStreaming) {
6970   uint8_t group_size = 2;
6971   int group_id = 2;
6972 
6973   // Report working CSIS
6974   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
6975   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
6976           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
6977 
6978   // First earbud
6979   const RawAddress test_address0 = GetTestAddress(0);
6980   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
6981   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
6982                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
6983 
6984   // Second earbud
6985   const RawAddress test_address1 = GetTestAddress(1);
6986   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
6987   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
6988                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
6989                     true /*connect_through_csis*/);
6990 
6991   // Start streaming
6992   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
6993   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
6994   LeAudioClient::Get()->GroupSetActive(group_id);
6995   SyncOnMainLoop();
6996 
6997   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
6998 
6999   /* Make sure configurations are non empty */
7000   btle_audio_codec_config_t call_config = {.codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7001                                            .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_32000HZ,
7002                                            .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7003                                            .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7004                                            .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7005                                            .octets_per_frame = 80};
7006 
7007   EXPECT_CALL(mock_audio_hal_client_callbacks_,
7008               OnAudioGroupCurrentCodecConf(group_id, call_config, call_config))
7009           .Times(1);
7010 
7011   StartStreaming(AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_CONTENT_TYPE_SPEECH, group_id);
7012 
7013   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
7014   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
7015   SyncOnMainLoop();
7016 
7017   // Verify Data transfer on two peer sinks and one source
7018   uint8_t cis_count_out = 2;
7019   uint8_t cis_count_in = 2;
7020   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 40);
7021 
7022   // Suspend
7023   LeAudioClient::Get()->GroupSuspend(group_id);
7024   SyncOnMainLoop();
7025 
7026   // Resume
7027   StartStreaming(AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_CONTENT_TYPE_SPEECH, group_id);
7028   SyncOnMainLoop();
7029   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
7030 
7031   // Verify Data transfer still works
7032   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 40);
7033 
7034   ASSERT_NE(0lu, streaming_groups.count(group_id));
7035   auto group = streaming_groups.at(group_id);
7036 
7037   // Stop
7038   StopStreaming(group_id, true);
7039   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
7040 
7041   // Check if cache configuration is still present
7042   ASSERT_TRUE(group->GetCachedConfiguration(types::LeAudioContextType::CONVERSATIONAL)
7043                       ->confs.get(le_audio::types::kLeAudioDirectionSink)
7044                       .size());
7045   ASSERT_TRUE(group->GetCachedConfiguration(types::LeAudioContextType::CONVERSATIONAL)
7046                       ->confs.get(le_audio::types::kLeAudioDirectionSource)
7047                       .size());
7048 
7049   // Release
7050   EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop()).Times(1);
7051   EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(1);
7052   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Stop()).Times(1);
7053   EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(1);
7054   LeAudioClient::Get()->GroupSetActive(bluetooth::groups::kGroupUnknown);
7055   SyncOnMainLoop();
7056 
7057   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
7058 
7059   // Setting group inactive, shall not change cached configuration
7060   ASSERT_TRUE(group->GetCachedConfiguration(types::LeAudioContextType::CONVERSATIONAL)
7061                       ->confs.get(le_audio::types::kLeAudioDirectionSink)
7062                       .size());
7063   ASSERT_TRUE(group->GetCachedConfiguration(types::LeAudioContextType::CONVERSATIONAL)
7064                       ->confs.get(le_audio::types::kLeAudioDirectionSource)
7065                       .size());
7066 }
7067 
TEST_F(UnicastTest,TestSetValidSingleOutputPreferredCodecConfig)7068 TEST_F(UnicastTest, TestSetValidSingleOutputPreferredCodecConfig) {
7069   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7070 
7071   btle_audio_codec_config_t preferred_output_codec_config = {
7072           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7073           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_24000HZ,
7074           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7075           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7076           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7077           .octets_per_frame = 60};
7078   // We did not set input preferred codec config
7079   btle_audio_codec_config_t empty_input_codec_config;
7080 
7081   int group_id = 2;
7082   TestSetupRemoteDevices(group_id);
7083   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
7084   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
7085   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
7086 
7087   ASSERT_EQ(LeAudioClient::Get()->IsUsingPreferredCodecConfig(
7088                     group_id, static_cast<int>(types::LeAudioContextType::MEDIA)),
7089             false);
7090   do_in_main_thread(base::BindOnce(&LeAudioClient::SetCodecConfigPreference,
7091                                    base::Unretained(LeAudioClient::Get()), group_id,
7092                                    empty_input_codec_config, preferred_output_codec_config));
7093   SyncOnMainLoop();
7094   ASSERT_EQ(LeAudioClient::Get()->IsUsingPreferredCodecConfig(
7095                     group_id, static_cast<int>(types::LeAudioContextType::MEDIA)),
7096             true);
7097   // We only set output preferred codec config so bidirectional context would
7098   // use default config
7099   ASSERT_EQ(LeAudioClient::Get()->IsUsingPreferredCodecConfig(
7100                     group_id, static_cast<int>(types::LeAudioContextType::CONVERSATIONAL)),
7101             false);
7102 }
7103 
TEST_F(UnicastTest,TestSetPreferredCodecConfigToNonActiveGroup)7104 TEST_F(UnicastTest, TestSetPreferredCodecConfigToNonActiveGroup) {
7105   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7106 
7107   int group_id = 2;
7108   TestSetupRemoteDevices(group_id);
7109   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
7110   ASSERT_EQ(LeAudioClient::Get()->IsUsingPreferredCodecConfig(
7111                     group_id, static_cast<int>(types::LeAudioContextType::MEDIA)),
7112             false);
7113 
7114   // Inactivate group 2
7115   LeAudioClient::Get()->GroupSetActive(bluetooth::groups::kGroupUnknown);
7116 
7117   btle_audio_codec_config_t preferred_codec_config = {
7118           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7119           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_16000HZ,
7120           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7121           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7122           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7123           .octets_per_frame = 40};
7124 
7125   // Re-initialize mock for destroyed hal client
7126   RegisterSourceHalClientMock();
7127   RegisterSinkHalClientMock();
7128 
7129   // Reconfiguration not needed as set preferred config to non active group
7130   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(0);
7131   EXPECT_CALL(*mock_le_audio_source_hal_client_, ReconfigurationComplete()).Times(0);
7132 
7133   do_in_main_thread(base::BindOnce(&LeAudioClient::SetCodecConfigPreference,
7134                                    base::Unretained(LeAudioClient::Get()), group_id,
7135                                    preferred_codec_config, preferred_codec_config));
7136   SyncOnMainLoop();
7137 
7138   ASSERT_EQ(LeAudioClient::Get()->IsUsingPreferredCodecConfig(
7139                     group_id, static_cast<int>(types::LeAudioContextType::MEDIA)),
7140             true);
7141   Mock::VerifyAndClearExpectations(&mock_state_machine_);
7142   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
7143 
7144   // Activate group 2 again
7145   do_in_main_thread(base::BindOnce(&LeAudioClient::GroupSetActive,
7146                                    base::Unretained(LeAudioClient::Get()), group_id));
7147   SyncOnMainLoop();
7148 
7149   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
7150   ASSERT_EQ(LeAudioClient::Get()->IsUsingPreferredCodecConfig(
7151                     group_id, static_cast<int>(types::LeAudioContextType::MEDIA)),
7152             true);
7153 }
7154 
TEST_F(UnicastTest,TwoEarbudsClearPreferenceBeforeMedia)7155 TEST_F(UnicastTest, TwoEarbudsClearPreferenceBeforeMedia) {
7156   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7157 
7158   int group_id = 2;
7159   TestSetupRemoteDevices(group_id);
7160 
7161   btle_audio_codec_config_t preferred_codec_config_before_media = {.codec_priority = -1};
7162 
7163   bool set_before_media = true;
7164   bool set_while_media = false;
7165   bool is_using_set_before_media_codec_during_media = false;
7166   bool is_using_set_while_media_codec_during_media = false;
7167   // Use legacy codec and should not reconfig while streaming
7168   bool is_reconfig = false;
7169   TestSetCodecPreference(&preferred_codec_config_before_media, nullptr, LeAudioContextType::MEDIA,
7170                          group_id, set_before_media, set_while_media,
7171                          is_using_set_before_media_codec_during_media,
7172                          is_using_set_while_media_codec_during_media, is_reconfig);
7173 }
7174 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceSuccessBeforeMedia)7175 TEST_F(UnicastTest, TwoEarbudsSetPreferenceSuccessBeforeMedia) {
7176   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7177 
7178   int group_id = 2;
7179   TestSetupRemoteDevices(group_id);
7180 
7181   // This codec can be used by media
7182   btle_audio_codec_config_t preferred_codec_config_before_media = {
7183           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7184           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_16000HZ,
7185           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7186           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7187           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7188           .octets_per_frame = 40};
7189 
7190   bool set_before_media = true;
7191   bool set_while_media = false;
7192   bool is_using_set_before_media_codec_during_media = true;
7193   bool is_using_set_while_media_codec_during_media = false;
7194   // Use preferred codec and should not reconfig while streaming
7195   bool is_reconfig = false;
7196   TestSetCodecPreference(&preferred_codec_config_before_media, nullptr, LeAudioContextType::MEDIA,
7197                          group_id, set_before_media, set_while_media,
7198                          is_using_set_before_media_codec_during_media,
7199                          is_using_set_while_media_codec_during_media, is_reconfig);
7200 }
7201 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceFailBeforeMedia)7202 TEST_F(UnicastTest, TwoEarbudsSetPreferenceFailBeforeMedia) {
7203   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7204 
7205   int group_id = 2;
7206   TestSetupRemoteDevices(group_id);
7207 
7208   // This codec can not be used by media
7209   btle_audio_codec_config_t preferred_codec_config_before_media = {
7210           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7211           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_16000HZ,
7212           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7213           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7214           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7215           .octets_per_frame = 70};
7216 
7217   bool set_before_media = true;
7218   bool set_while_media = false;
7219   bool is_using_set_before_media_codec_during_media = false;
7220   bool is_using_set_while_media_codec_during_media = false;
7221   // Use legacy codec and should not reconfig while streaming
7222   bool is_reconfig = false;
7223   TestSetCodecPreference(&preferred_codec_config_before_media, nullptr, LeAudioContextType::MEDIA,
7224                          group_id, set_before_media, set_while_media,
7225                          is_using_set_before_media_codec_during_media,
7226                          is_using_set_while_media_codec_during_media, is_reconfig);
7227 }
7228 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceSuccessDuringMediaWithReconfig)7229 TEST_F(UnicastTest, TwoEarbudsSetPreferenceSuccessDuringMediaWithReconfig) {
7230   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7231 
7232   int group_id = 2;
7233   TestSetupRemoteDevices(group_id);
7234 
7235   // This codec can be used by media
7236   btle_audio_codec_config_t preferred_codec_config_during_media = {
7237           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7238           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_24000HZ,
7239           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7240           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7241           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7242           .octets_per_frame = 60};
7243 
7244   bool set_before_media = false;
7245   bool set_while_media = true;
7246   bool is_using_set_before_media_codec_during_media = false;
7247   bool is_using_set_while_media_codec_during_media = true;
7248   // Should reconfig and use preferred codec while streaming
7249   bool is_reconfig = true;
7250   TestSetCodecPreference(nullptr, &preferred_codec_config_during_media, LeAudioContextType::MEDIA,
7251                          group_id, set_before_media, set_while_media,
7252                          is_using_set_before_media_codec_during_media,
7253                          is_using_set_while_media_codec_during_media, is_reconfig);
7254 }
7255 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceSuccessDuringMediaWithoutReconfig)7256 TEST_F(UnicastTest, TwoEarbudsSetPreferenceSuccessDuringMediaWithoutReconfig) {
7257   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7258 
7259   int group_id = 2;
7260   TestSetupRemoteDevices(group_id);
7261 
7262   // This codec can be used by media
7263   btle_audio_codec_config_t preferred_codec_config_during_media = {
7264           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7265           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_48000HZ,
7266           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7267           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7268           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7269           .octets_per_frame = 120};
7270 
7271   bool set_before_media = false;
7272   bool set_while_media = true;
7273   bool is_using_set_before_media_codec_during_media = false;
7274   bool is_using_set_while_media_codec_during_media = true;
7275   // Use preferred codec but not reconfig while streaming since same codec with
7276   // original
7277   bool is_reconfig = false;
7278   TestSetCodecPreference(nullptr, &preferred_codec_config_during_media, LeAudioContextType::MEDIA,
7279                          group_id, set_before_media, set_while_media,
7280                          is_using_set_before_media_codec_during_media,
7281                          is_using_set_while_media_codec_during_media, is_reconfig);
7282 }
7283 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceFailDuringMediaWithoutReconfig)7284 TEST_F(UnicastTest, TwoEarbudsSetPreferenceFailDuringMediaWithoutReconfig) {
7285   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7286 
7287   int group_id = 2;
7288   TestSetupRemoteDevices(group_id);
7289 
7290   // This codec can not be used by media
7291   btle_audio_codec_config_t preferred_codec_config_during_media = {
7292           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7293           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_16000HZ,
7294           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7295           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7296           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7297           .octets_per_frame = 70};
7298 
7299   bool set_before_media = false;
7300   bool set_while_media = true;
7301   bool is_using_set_before_media_codec_during_media = false;
7302   bool is_using_set_while_media_codec_during_media = false;
7303   // Use original codec and should not reconfig while streaming
7304   bool is_reconfig = false;
7305   TestSetCodecPreference(nullptr, &preferred_codec_config_during_media, LeAudioContextType::MEDIA,
7306                          group_id, set_before_media, set_while_media,
7307                          is_using_set_before_media_codec_during_media,
7308                          is_using_set_while_media_codec_during_media, is_reconfig);
7309 }
7310 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceSucessBeforeMediaClearPreferenceDuringMediaWithReconfig)7311 TEST_F(UnicastTest,
7312        TwoEarbudsSetPreferenceSucessBeforeMediaClearPreferenceDuringMediaWithReconfig) {
7313   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7314 
7315   int group_id = 2;
7316   TestSetupRemoteDevices(group_id);
7317 
7318   // This codec can be used by media
7319   btle_audio_codec_config_t preferred_codec_config_before_media = {
7320           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7321           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_16000HZ,
7322           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7323           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7324           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7325           .octets_per_frame = 40};
7326   btle_audio_codec_config_t preferred_codec_config_during_media = {.codec_priority = -1};
7327 
7328   bool set_before_media = true;
7329   bool set_while_media = true;
7330   bool is_using_set_before_media_codec_during_media = true;
7331   bool is_using_set_while_media_codec_during_media = false;
7332   // Should reconfig to legacy codec while streaming as we clear preferred codec
7333   bool is_reconfig = true;
7334   TestSetCodecPreference(&preferred_codec_config_before_media, &preferred_codec_config_during_media,
7335                          LeAudioContextType::MEDIA, group_id, set_before_media, set_while_media,
7336                          is_using_set_before_media_codec_during_media,
7337                          is_using_set_while_media_codec_during_media, is_reconfig);
7338 }
7339 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceSucessBeforeMediaSetPreferenceSuccessDuringMediaWithReconfig)7340 TEST_F(UnicastTest,
7341        TwoEarbudsSetPreferenceSucessBeforeMediaSetPreferenceSuccessDuringMediaWithReconfig) {
7342   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7343 
7344   int group_id = 2;
7345   TestSetupRemoteDevices(group_id);
7346 
7347   // This codec can be used by media
7348   btle_audio_codec_config_t preferred_codec_config_before_media = {
7349           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7350           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_16000HZ,
7351           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7352           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7353           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7354           .octets_per_frame = 40};
7355   // This codec can be used by media
7356   btle_audio_codec_config_t preferred_codec_config_during_media = {
7357           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7358           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_24000HZ,
7359           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7360           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7361           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7362           .octets_per_frame = 60};
7363 
7364   bool set_before_media = true;
7365   bool set_while_media = true;
7366   bool is_using_set_before_media_codec_during_media = true;
7367   bool is_using_set_while_media_codec_during_media = true;
7368   // Should reconfig to new preferred codec from old preferred codec while streaming
7369   bool is_reconfig = true;
7370   TestSetCodecPreference(&preferred_codec_config_before_media, &preferred_codec_config_during_media,
7371                          LeAudioContextType::MEDIA, group_id, set_before_media, set_while_media,
7372                          is_using_set_before_media_codec_during_media,
7373                          is_using_set_while_media_codec_during_media, is_reconfig);
7374 }
7375 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceSucessBeforeMediaSetPreferenceSuccessDuringMediaWithoutReconfig)7376 TEST_F(UnicastTest,
7377        TwoEarbudsSetPreferenceSucessBeforeMediaSetPreferenceSuccessDuringMediaWithoutReconfig) {
7378   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7379 
7380   int group_id = 2;
7381   TestSetupRemoteDevices(group_id);
7382 
7383   // This codec can be used by media
7384   btle_audio_codec_config_t preferred_codec_config_before_media = {
7385           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7386           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_16000HZ,
7387           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7388           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7389           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7390           .octets_per_frame = 40};
7391   // This codec can be used by media
7392   btle_audio_codec_config_t preferred_codec_config_during_media = {
7393           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7394           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_16000HZ,
7395           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7396           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7397           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7398           .octets_per_frame = 40};
7399 
7400   bool set_before_media = true;
7401   bool set_while_media = true;
7402   bool is_using_set_before_media_codec_during_media = true;
7403   bool is_using_set_while_media_codec_during_media = true;
7404   // Should not reconfig while streaming because same as previous preferred codec
7405   bool is_reconfig = false;
7406   TestSetCodecPreference(&preferred_codec_config_before_media, &preferred_codec_config_during_media,
7407                          LeAudioContextType::MEDIA, group_id, set_before_media, set_while_media,
7408                          is_using_set_before_media_codec_during_media,
7409                          is_using_set_while_media_codec_during_media, is_reconfig);
7410 }
7411 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceSucessBeforeMediaSetPreferenceFailDuringMediaWithReconfig)7412 TEST_F(UnicastTest,
7413        TwoEarbudsSetPreferenceSucessBeforeMediaSetPreferenceFailDuringMediaWithReconfig) {
7414   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7415 
7416   int group_id = 2;
7417   TestSetupRemoteDevices(group_id);
7418 
7419   // This codec can be used by media
7420   btle_audio_codec_config_t preferred_codec_config_before_media = {
7421           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7422           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_16000HZ,
7423           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7424           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7425           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7426           .octets_per_frame = 40};
7427   // This codec can not be used by media
7428   btle_audio_codec_config_t preferred_codec_config_during_media = {
7429           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7430           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_16000HZ,
7431           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7432           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7433           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7434           .octets_per_frame = 70};
7435 
7436   bool set_before_media = true;
7437   bool set_while_media = true;
7438   bool is_using_set_before_media_codec_during_media = true;
7439   bool is_using_set_while_media_codec_during_media = false;
7440   // Should reconfig to legacy codec while streaming because invalid preferred codec
7441   bool is_reconfig = true;
7442   TestSetCodecPreference(&preferred_codec_config_before_media, &preferred_codec_config_during_media,
7443                          LeAudioContextType::MEDIA, group_id, set_before_media, set_while_media,
7444                          is_using_set_before_media_codec_during_media,
7445                          is_using_set_while_media_codec_during_media, is_reconfig);
7446 }
7447 
TEST_F(UnicastTest,TwoEarbudsClearPreferenceBeforeConv)7448 TEST_F(UnicastTest, TwoEarbudsClearPreferenceBeforeConv) {
7449   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7450 
7451   int group_id = 2;
7452   TestSetupRemoteDevices(group_id);
7453 
7454   btle_audio_codec_config_t preferred_codec_config_before_conv = {.codec_priority = -1};
7455 
7456   // SetInCall is used by GTBS - and only then we can expect CCID to be set.
7457   LeAudioClient::Get()->SetInCall(true);
7458 
7459   bool set_before_conv = true;
7460   bool set_while_conv = false;
7461   bool is_using_set_before_conv_codec_during_conv = false;
7462   bool is_using_set_while_conv_codec_during_conv = false;
7463   // Use legacy codec and should not reconfig while streaming
7464   bool is_reconfig = false;
7465   TestSetCodecPreference(&preferred_codec_config_before_conv, nullptr,
7466                          LeAudioContextType::CONVERSATIONAL, group_id, set_before_conv,
7467                          set_while_conv, is_using_set_before_conv_codec_during_conv,
7468                          is_using_set_while_conv_codec_during_conv, is_reconfig);
7469   LeAudioClient::Get()->SetInCall(false);
7470 }
7471 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceSuccessBeforeConv)7472 TEST_F(UnicastTest, TwoEarbudsSetPreferenceSuccessBeforeConv) {
7473   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7474 
7475   int group_id = 2;
7476   TestSetupRemoteDevices(group_id);
7477 
7478   // This codec can be used by conv
7479   btle_audio_codec_config_t preferred_codec_config_before_conv = {
7480           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7481           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_16000HZ,
7482           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7483           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7484           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7485           .octets_per_frame = 40};
7486 
7487   // SetInCall is used by GTBS - and only then we can expect CCID to be set.
7488   LeAudioClient::Get()->SetInCall(true);
7489 
7490   bool set_before_conv = true;
7491   bool set_while_conv = false;
7492   bool is_using_set_before_conv_codec_during_conv = true;
7493   bool is_using_set_while_conv_codec_during_conv = false;
7494   // Use preferred codec and should not reconfig while streaming
7495   bool is_reconfig = false;
7496   TestSetCodecPreference(&preferred_codec_config_before_conv, nullptr,
7497                          LeAudioContextType::CONVERSATIONAL, group_id, set_before_conv,
7498                          set_while_conv, is_using_set_before_conv_codec_during_conv,
7499                          is_using_set_while_conv_codec_during_conv, is_reconfig);
7500   LeAudioClient::Get()->SetInCall(false);
7501 }
7502 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceFailBeforeConv)7503 TEST_F(UnicastTest, TwoEarbudsSetPreferenceFailBeforeConv) {
7504   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7505 
7506   int group_id = 2;
7507   TestSetupRemoteDevices(group_id);
7508 
7509   // This codec can not be used by conv
7510   btle_audio_codec_config_t preferred_codec_config_before_conv = {
7511           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7512           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_16000HZ,
7513           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7514           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7515           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7516           .octets_per_frame = 70};
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 = true;
7522   bool set_while_conv = false;
7523   bool is_using_set_before_conv_codec_during_conv = false;
7524   bool is_using_set_while_conv_codec_during_conv = false;
7525   // Use legacy codec and should not reconfig while streaming
7526   bool is_reconfig = false;
7527   TestSetCodecPreference(&preferred_codec_config_before_conv, nullptr,
7528                          LeAudioContextType::CONVERSATIONAL, group_id, set_before_conv,
7529                          set_while_conv, is_using_set_before_conv_codec_during_conv,
7530                          is_using_set_while_conv_codec_during_conv, is_reconfig);
7531   LeAudioClient::Get()->SetInCall(false);
7532 }
7533 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceSuccessDuringConvWithReconfig)7534 TEST_F(UnicastTest, TwoEarbudsSetPreferenceSuccessDuringConvWithReconfig) {
7535   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7536 
7537   int group_id = 2;
7538   TestSetupRemoteDevices(group_id);
7539 
7540   // This codec can be used by conv
7541   btle_audio_codec_config_t preferred_codec_config_during_conv = {
7542           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7543           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_16000HZ,
7544           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7545           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7546           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7547           .octets_per_frame = 40};
7548 
7549   // SetInCall is used by GTBS - and only then we can expect CCID to be set.
7550   LeAudioClient::Get()->SetInCall(true);
7551 
7552   bool set_before_conv = false;
7553   bool set_while_conv = true;
7554   bool is_using_set_before_conv_codec_during_conv = false;
7555   bool is_using_set_while_conv_codec_during_conv = true;
7556   // Should reconfig and use preferred codec while streaming
7557   bool is_reconfig = true;
7558   TestSetCodecPreference(nullptr, &preferred_codec_config_during_conv,
7559                          LeAudioContextType::CONVERSATIONAL, group_id, set_before_conv,
7560                          set_while_conv, is_using_set_before_conv_codec_during_conv,
7561                          is_using_set_while_conv_codec_during_conv, is_reconfig);
7562   LeAudioClient::Get()->SetInCall(false);
7563 }
7564 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceSuccessDuringConvWithoutReconfig)7565 TEST_F(UnicastTest, TwoEarbudsSetPreferenceSuccessDuringConvWithoutReconfig) {
7566   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7567 
7568   int group_id = 2;
7569   TestSetupRemoteDevices(group_id);
7570 
7571   // This codec can be used by conv
7572   btle_audio_codec_config_t preferred_codec_config_during_conv = {
7573           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7574           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_32000HZ,
7575           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7576           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7577           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7578           .octets_per_frame = 80};
7579 
7580   // SetInCall is used by GTBS - and only then we can expect CCID to be set.
7581   LeAudioClient::Get()->SetInCall(true);
7582 
7583   bool set_before_conv = false;
7584   bool set_while_conv = true;
7585   bool is_using_set_before_conv_codec_during_conv = false;
7586   bool is_using_set_while_conv_codec_during_conv = true;
7587   // Use preferred codec but not reconfig while streaming since same codec with
7588   // original
7589   bool is_reconfig = false;
7590   TestSetCodecPreference(nullptr, &preferred_codec_config_during_conv,
7591                          LeAudioContextType::CONVERSATIONAL, group_id, set_before_conv,
7592                          set_while_conv, is_using_set_before_conv_codec_during_conv,
7593                          is_using_set_while_conv_codec_during_conv, is_reconfig);
7594   LeAudioClient::Get()->SetInCall(false);
7595 }
7596 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceFailDuringConvWithoutReconfig)7597 TEST_F(UnicastTest, TwoEarbudsSetPreferenceFailDuringConvWithoutReconfig) {
7598   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7599 
7600   int group_id = 2;
7601   TestSetupRemoteDevices(group_id);
7602 
7603   // This codec can not be used by conv
7604   btle_audio_codec_config_t preferred_codec_config_during_conv = {
7605           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7606           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_16000HZ,
7607           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7608           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7609           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7610           .octets_per_frame = 70};
7611 
7612   // SetInCall is used by GTBS - and only then we can expect CCID to be set.
7613   LeAudioClient::Get()->SetInCall(true);
7614 
7615   bool set_before_conv = false;
7616   bool set_while_conv = true;
7617   bool is_using_set_before_conv_codec_during_conv = false;
7618   bool is_using_set_while_conv_codec_during_conv = false;
7619   // Use original codec and should not reconfig while streaming
7620   bool is_reconfig = false;
7621   TestSetCodecPreference(nullptr, &preferred_codec_config_during_conv,
7622                          LeAudioContextType::CONVERSATIONAL, group_id, set_before_conv,
7623                          set_while_conv, is_using_set_before_conv_codec_during_conv,
7624                          is_using_set_while_conv_codec_during_conv, is_reconfig);
7625   LeAudioClient::Get()->SetInCall(false);
7626 }
7627 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceSucessBeforeConvClearPreferenceDuringConvWithReconfig)7628 TEST_F(UnicastTest, TwoEarbudsSetPreferenceSucessBeforeConvClearPreferenceDuringConvWithReconfig) {
7629   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7630 
7631   int group_id = 2;
7632   TestSetupRemoteDevices(group_id);
7633 
7634   // This codec can be used by conv
7635   btle_audio_codec_config_t preferred_codec_config_before_conv = {
7636           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7637           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_16000HZ,
7638           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7639           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7640           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7641           .octets_per_frame = 40};
7642   btle_audio_codec_config_t preferred_codec_config_during_conv = {.codec_priority = -1};
7643 
7644   // SetInCall is used by GTBS - and only then we can expect CCID to be set.
7645   LeAudioClient::Get()->SetInCall(true);
7646 
7647   bool set_before_conv = true;
7648   bool set_while_conv = true;
7649   bool is_using_set_before_conv_codec_during_conv = true;
7650   bool is_using_set_while_conv_codec_during_conv = false;
7651   // Should reconfig to legacy codec while streaming as we clear preferred codec
7652   bool is_reconfig = true;
7653   TestSetCodecPreference(&preferred_codec_config_before_conv, &preferred_codec_config_during_conv,
7654                          LeAudioContextType::CONVERSATIONAL, group_id, set_before_conv,
7655                          set_while_conv, is_using_set_before_conv_codec_during_conv,
7656                          is_using_set_while_conv_codec_during_conv, is_reconfig);
7657   LeAudioClient::Get()->SetInCall(false);
7658 }
7659 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceSucessBeforeConvSetPreferenceSuccessDuringConvWithReconfig)7660 TEST_F(UnicastTest,
7661        TwoEarbudsSetPreferenceSucessBeforeConvSetPreferenceSuccessDuringConvWithReconfig) {
7662   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7663 
7664   int group_id = 2;
7665   TestSetupRemoteDevices(group_id);
7666 
7667   // This codec can be used by conv
7668   btle_audio_codec_config_t preferred_codec_config_before_conv = {
7669           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7670           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_16000HZ,
7671           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7672           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7673           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7674           .octets_per_frame = 40};
7675   // This codec can be used by conv
7676   btle_audio_codec_config_t preferred_codec_config_during_conv = {
7677           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7678           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_32000HZ,
7679           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7680           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7681           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7682           .octets_per_frame = 80};
7683 
7684   // SetInCall is used by GTBS - and only then we can expect CCID to be set.
7685   LeAudioClient::Get()->SetInCall(true);
7686 
7687   bool set_before_conv = true;
7688   bool set_while_conv = true;
7689   bool is_using_set_before_conv_codec_during_conv = true;
7690   bool is_using_set_while_conv_codec_during_conv = true;
7691   // Should reconfig to new preferred codec from old preferred codec while
7692   // streaming
7693   bool is_reconfig = true;
7694   TestSetCodecPreference(&preferred_codec_config_before_conv, &preferred_codec_config_during_conv,
7695                          LeAudioContextType::CONVERSATIONAL, group_id, set_before_conv,
7696                          set_while_conv, is_using_set_before_conv_codec_during_conv,
7697                          is_using_set_while_conv_codec_during_conv, is_reconfig);
7698   LeAudioClient::Get()->SetInCall(false);
7699 }
7700 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceSucessBeforeConvSetPreferenceSuccessDuringConvWithoutReconfig)7701 TEST_F(UnicastTest,
7702        TwoEarbudsSetPreferenceSucessBeforeConvSetPreferenceSuccessDuringConvWithoutReconfig) {
7703   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7704 
7705   int group_id = 2;
7706   TestSetupRemoteDevices(group_id);
7707 
7708   // This codec can be used by conv
7709   btle_audio_codec_config_t preferred_codec_config_before_conv = {
7710           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7711           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_16000HZ,
7712           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7713           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7714           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7715           .octets_per_frame = 40};
7716   // This codec can be used by conv
7717   btle_audio_codec_config_t preferred_codec_config_during_conv = {
7718           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7719           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_16000HZ,
7720           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7721           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7722           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7723           .octets_per_frame = 40};
7724 
7725   // SetInCall is used by GTBS - and only then we can expect CCID to be set.
7726   LeAudioClient::Get()->SetInCall(true);
7727 
7728   bool set_before_conv = true;
7729   bool set_while_conv = true;
7730   bool is_using_set_before_conv_codec_during_conv = true;
7731   bool is_using_set_while_conv_codec_during_conv = true;
7732   // Should not reconfig while streaming because same as previous preferred
7733   // codec
7734   bool is_reconfig = false;
7735   TestSetCodecPreference(&preferred_codec_config_before_conv, &preferred_codec_config_during_conv,
7736                          LeAudioContextType::CONVERSATIONAL, group_id, set_before_conv,
7737                          set_while_conv, is_using_set_before_conv_codec_during_conv,
7738                          is_using_set_while_conv_codec_during_conv, is_reconfig);
7739   LeAudioClient::Get()->SetInCall(false);
7740 }
7741 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceSucessBeforeConvSetPreferenceFailDuringConvWithReconfig)7742 TEST_F(UnicastTest,
7743        TwoEarbudsSetPreferenceSucessBeforeConvSetPreferenceFailDuringConvWithReconfig) {
7744   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7745 
7746   int group_id = 2;
7747   TestSetupRemoteDevices(group_id);
7748 
7749   // This codec can be used by conv
7750   btle_audio_codec_config_t preferred_codec_config_before_conv = {
7751           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7752           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_16000HZ,
7753           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7754           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7755           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7756           .octets_per_frame = 40};
7757   // This codec can not be used by conv
7758   btle_audio_codec_config_t preferred_codec_config_during_conv = {
7759           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7760           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_16000HZ,
7761           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7762           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7763           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7764           .octets_per_frame = 70};
7765 
7766   // SetInCall is used by GTBS - and only then we can expect CCID to be set.
7767   LeAudioClient::Get()->SetInCall(true);
7768 
7769   bool set_before_conv = true;
7770   bool set_while_conv = true;
7771   bool is_using_set_before_conv_codec_during_conv = true;
7772   bool is_using_set_while_conv_codec_during_conv = false;
7773   // Should reconfig to legacy codec while streaming because invalid preferred
7774   // codec
7775   bool is_reconfig = true;
7776   TestSetCodecPreference(&preferred_codec_config_before_conv, &preferred_codec_config_during_conv,
7777                          LeAudioContextType::CONVERSATIONAL, group_id, set_before_conv,
7778                          set_while_conv, is_using_set_before_conv_codec_during_conv,
7779                          is_using_set_while_conv_codec_during_conv, is_reconfig);
7780   LeAudioClient::Get()->SetInCall(false);
7781 }
7782 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceWhenIdleForBothMediaAndConv)7783 TEST_F(UnicastTest, TwoEarbudsSetPreferenceWhenIdleForBothMediaAndConv) {
7784   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7785 
7786   int group_id = 2;
7787   TestSetupRemoteDevices(group_id);
7788 
7789   // This codec can be used by media and conv
7790   btle_audio_codec_config_t preferred_codec_config_before_media = {
7791           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7792           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_16000HZ,
7793           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7794           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7795           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7796           .octets_per_frame = 40};
7797 
7798   bool set_before_media = true;
7799   bool set_while_media = false;
7800   bool is_using_set_before_media_codec_during_media = true;
7801   bool is_using_set_while_media_codec_during_media = false;
7802   bool is_reconfig = false;
7803   TestSetCodecPreference(&preferred_codec_config_before_media, nullptr, LeAudioContextType::MEDIA,
7804                          group_id, set_before_media, set_while_media,
7805                          is_using_set_before_media_codec_during_media,
7806                          is_using_set_while_media_codec_during_media, is_reconfig);
7807 
7808   // simulate suspend timeout passed, alarm executing
7809   fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
7810   SyncOnMainLoop();
7811 
7812   // SetInCall is used by GTBS - and only then we can expect CCID to be set.
7813   LeAudioClient::Get()->SetInCall(true);
7814 
7815   bool set_before_conv = false;
7816   bool set_while_conv = false;
7817   bool is_using_set_before_conv_codec_during_conv = true;
7818   bool is_using_set_while_conv_codec_during_conv = false;
7819   is_reconfig = false;
7820   TestSetCodecPreference(nullptr, nullptr, LeAudioContextType::CONVERSATIONAL, group_id,
7821                          set_before_conv, set_while_conv,
7822                          is_using_set_before_conv_codec_during_conv,
7823                          is_using_set_while_conv_codec_during_conv, is_reconfig);
7824   LeAudioClient::Get()->SetInCall(false);
7825 
7826   // should use preferred codec when switching back to media
7827   ASSERT_EQ(LeAudioClient::Get()->IsUsingPreferredCodecConfig(
7828                     group_id, static_cast<int>(types::LeAudioContextType::MEDIA)),
7829             true);
7830 }
7831 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceWhenIdleForMediaNotForConv)7832 TEST_F(UnicastTest, TwoEarbudsSetPreferenceWhenIdleForMediaNotForConv) {
7833   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7834 
7835   int group_id = 2;
7836   TestSetupRemoteDevices(group_id);
7837 
7838   // This codec can be used by media but not by conv
7839   btle_audio_codec_config_t preferred_codec_config_before_media = {
7840           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7841           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_24000HZ,
7842           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7843           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7844           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7845           .octets_per_frame = 60};
7846 
7847   bool set_before_media = true;
7848   bool set_while_media = false;
7849   bool is_using_set_before_media_codec_during_media = true;
7850   bool is_using_set_while_media_codec_during_media = false;
7851   bool is_reconfig = false;
7852   TestSetCodecPreference(&preferred_codec_config_before_media, nullptr, LeAudioContextType::MEDIA,
7853                          group_id, set_before_media, set_while_media,
7854                          is_using_set_before_media_codec_during_media,
7855                          is_using_set_while_media_codec_during_media, is_reconfig);
7856 
7857   // simulate suspend timeout passed, alarm executing
7858   fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
7859   SyncOnMainLoop();
7860 
7861   // SetInCall is used by GTBS - and only then we can expect CCID to be set.
7862   LeAudioClient::Get()->SetInCall(true);
7863 
7864   bool set_before_conv = false;
7865   bool set_while_conv = false;
7866   bool is_using_set_before_conv_codec_during_conv = false;
7867   bool is_using_set_while_conv_codec_during_conv = false;
7868   is_reconfig = false;
7869   TestSetCodecPreference(nullptr, nullptr, LeAudioContextType::CONVERSATIONAL, group_id,
7870                          set_before_conv, set_while_conv,
7871                          is_using_set_before_conv_codec_during_conv,
7872                          is_using_set_while_conv_codec_during_conv, is_reconfig);
7873   LeAudioClient::Get()->SetInCall(false);
7874 
7875   // should use preferred codec when switching back to media
7876   ASSERT_EQ(LeAudioClient::Get()->IsUsingPreferredCodecConfig(
7877                     group_id, static_cast<int>(types::LeAudioContextType::MEDIA)),
7878             true);
7879 }
7880 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceWhenIdleNotForMediaForConv)7881 TEST_F(UnicastTest, TwoEarbudsSetPreferenceWhenIdleNotForMediaForConv) {
7882   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7883 
7884   int group_id = 2;
7885   TestSetupRemoteDevices(group_id);
7886 
7887   // This codec can not be used by media but by conv
7888   btle_audio_codec_config_t preferred_codec_config_before_media = {
7889           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7890           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_32000HZ,
7891           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7892           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7893           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7894           .octets_per_frame = 80};
7895 
7896   bool set_before_media = true;
7897   bool set_while_media = false;
7898   bool is_using_set_before_media_codec_during_media = false;
7899   bool is_using_set_while_media_codec_during_media = false;
7900   bool is_reconfig = false;
7901   TestSetCodecPreference(&preferred_codec_config_before_media, nullptr, LeAudioContextType::MEDIA,
7902                          group_id, set_before_media, set_while_media,
7903                          is_using_set_before_media_codec_during_media,
7904                          is_using_set_while_media_codec_during_media, is_reconfig);
7905 
7906   // simulate suspend timeout passed, alarm executing
7907   fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
7908   SyncOnMainLoop();
7909 
7910   // SetInCall is used by GTBS - and only then we can expect CCID to be set.
7911   LeAudioClient::Get()->SetInCall(true);
7912 
7913   bool set_before_conv = false;
7914   bool set_while_conv = false;
7915   bool is_using_set_before_conv_codec_during_conv = true;
7916   bool is_using_set_while_conv_codec_during_conv = false;
7917   is_reconfig = false;
7918   TestSetCodecPreference(nullptr, nullptr, LeAudioContextType::CONVERSATIONAL, group_id,
7919                          set_before_conv, set_while_conv,
7920                          is_using_set_before_conv_codec_during_conv,
7921                          is_using_set_while_conv_codec_during_conv, is_reconfig);
7922   LeAudioClient::Get()->SetInCall(false);
7923 
7924   // should use legacy codec when switching back to media
7925   ASSERT_EQ(LeAudioClient::Get()->IsUsingPreferredCodecConfig(
7926                     group_id, static_cast<int>(types::LeAudioContextType::MEDIA)),
7927             false);
7928 }
7929 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceWhenIdleNotForBothMediaAndConv)7930 TEST_F(UnicastTest, TwoEarbudsSetPreferenceWhenIdleNotForBothMediaAndConv) {
7931   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7932 
7933   int group_id = 2;
7934   TestSetupRemoteDevices(group_id);
7935 
7936   // This codec can not be used by media and conv
7937   btle_audio_codec_config_t preferred_codec_config_before_media = {
7938           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7939           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_24000HZ,
7940           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7941           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7942           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7943           .octets_per_frame = 10};
7944 
7945   bool set_before_media = true;
7946   bool set_while_media = false;
7947   bool is_using_set_before_media_codec_during_media = false;
7948   bool is_using_set_while_media_codec_during_media = false;
7949   bool is_reconfig = false;
7950   TestSetCodecPreference(&preferred_codec_config_before_media, nullptr, LeAudioContextType::MEDIA,
7951                          group_id, set_before_media, set_while_media,
7952                          is_using_set_before_media_codec_during_media,
7953                          is_using_set_while_media_codec_during_media, is_reconfig);
7954 
7955   // simulate suspend timeout passed, alarm executing
7956   fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
7957   SyncOnMainLoop();
7958 
7959   // SetInCall is used by GTBS - and only then we can expect CCID to be set.
7960   LeAudioClient::Get()->SetInCall(true);
7961 
7962   bool set_before_conv = false;
7963   bool set_while_conv = false;
7964   bool is_using_set_before_conv_codec_during_conv = false;
7965   bool is_using_set_while_conv_codec_during_conv = false;
7966   is_reconfig = false;
7967   TestSetCodecPreference(nullptr, nullptr, LeAudioContextType::CONVERSATIONAL, group_id,
7968                          set_before_conv, set_while_conv,
7969                          is_using_set_before_conv_codec_during_conv,
7970                          is_using_set_while_conv_codec_during_conv, is_reconfig);
7971   LeAudioClient::Get()->SetInCall(false);
7972 
7973   // should use legacy codec when switching back to media
7974   ASSERT_EQ(LeAudioClient::Get()->IsUsingPreferredCodecConfig(
7975                     group_id, static_cast<int>(types::LeAudioContextType::MEDIA)),
7976             false);
7977 }
7978 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceWhenMediaForBothMediaAndConv)7979 TEST_F(UnicastTest, TwoEarbudsSetPreferenceWhenMediaForBothMediaAndConv) {
7980   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
7981 
7982   int group_id = 2;
7983   TestSetupRemoteDevices(group_id);
7984 
7985   // This codec can be used by media and conv
7986   btle_audio_codec_config_t preferred_codec_config_during_media = {
7987           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
7988           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_16000HZ,
7989           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
7990           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
7991           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
7992           .octets_per_frame = 40};
7993 
7994   bool set_before_media = false;
7995   bool set_while_media = true;
7996   bool is_using_set_before_media_codec_during_media = false;
7997   bool is_using_set_while_media_codec_during_media = true;
7998   // should use preferred codec and reconfig
7999   bool is_reconfig = true;
8000   TestSetCodecPreference(nullptr, &preferred_codec_config_during_media, LeAudioContextType::MEDIA,
8001                          group_id, set_before_media, set_while_media,
8002                          is_using_set_before_media_codec_during_media,
8003                          is_using_set_while_media_codec_during_media, is_reconfig);
8004 
8005   log::info("simulate suspend timeout passed, alarm executing");
8006   fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
8007   SyncOnMainLoop();
8008 
8009   log::info("SetInCall is used by GTBS - and only then we can expect CCID to be set.");
8010   LeAudioClient::Get()->SetInCall(true);
8011 
8012   bool set_before_conv = false;
8013   bool set_while_conv = false;
8014   bool is_using_set_before_conv_codec_during_conv = true;
8015   bool is_using_set_while_conv_codec_during_conv = false;
8016   is_reconfig = false;
8017   TestSetCodecPreference(nullptr, nullptr, LeAudioContextType::CONVERSATIONAL, group_id,
8018                          set_before_conv, set_while_conv,
8019                          is_using_set_before_conv_codec_during_conv,
8020                          is_using_set_while_conv_codec_during_conv, is_reconfig);
8021   LeAudioClient::Get()->SetInCall(false);
8022 
8023   log::info("should use preferred codec when switching back to media");
8024   ASSERT_EQ(LeAudioClient::Get()->IsUsingPreferredCodecConfig(
8025                     group_id, static_cast<int>(types::LeAudioContextType::MEDIA)),
8026             true);
8027 }
8028 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceWhenMediaForMediaNotForConv)8029 TEST_F(UnicastTest, TwoEarbudsSetPreferenceWhenMediaForMediaNotForConv) {
8030   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
8031 
8032   int group_id = 2;
8033   TestSetupRemoteDevices(group_id);
8034 
8035   // This codec can be used by media but not by conv
8036   btle_audio_codec_config_t preferred_codec_config_during_media = {
8037           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
8038           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_24000HZ,
8039           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
8040           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
8041           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
8042           .octets_per_frame = 60};
8043 
8044   bool set_before_media = false;
8045   bool set_while_media = true;
8046   bool is_using_set_before_media_codec_during_media = false;
8047   bool is_using_set_while_media_codec_during_media = true;
8048   // should use preferred codec and reconfig
8049   bool is_reconfig = true;
8050   TestSetCodecPreference(nullptr, &preferred_codec_config_during_media, LeAudioContextType::MEDIA,
8051                          group_id, set_before_media, set_while_media,
8052                          is_using_set_before_media_codec_during_media,
8053                          is_using_set_while_media_codec_during_media, is_reconfig);
8054 
8055   // simulate suspend timeout passed, alarm executing
8056   fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
8057   SyncOnMainLoop();
8058 
8059   // SetInCall is used by GTBS - and only then we can expect CCID to be set.
8060   LeAudioClient::Get()->SetInCall(true);
8061 
8062   bool set_before_conv = false;
8063   bool set_while_conv = false;
8064   bool is_using_set_before_conv_codec_during_conv = false;
8065   bool is_using_set_while_conv_codec_during_conv = false;
8066   is_reconfig = false;
8067   TestSetCodecPreference(nullptr, nullptr, LeAudioContextType::CONVERSATIONAL, group_id,
8068                          set_before_conv, set_while_conv,
8069                          is_using_set_before_conv_codec_during_conv,
8070                          is_using_set_while_conv_codec_during_conv, is_reconfig);
8071   LeAudioClient::Get()->SetInCall(false);
8072 
8073   // should use preferred codec when switching back to media
8074   ASSERT_EQ(LeAudioClient::Get()->IsUsingPreferredCodecConfig(
8075                     group_id, static_cast<int>(types::LeAudioContextType::MEDIA)),
8076             true);
8077 }
8078 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceWhenMediaNotForMediaForConv)8079 TEST_F(UnicastTest, TwoEarbudsSetPreferenceWhenMediaNotForMediaForConv) {
8080   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
8081 
8082   int group_id = 2;
8083   TestSetupRemoteDevices(group_id);
8084 
8085   // This codec can not be used by media and but by conv
8086   btle_audio_codec_config_t preferred_codec_config_during_media = {
8087           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
8088           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_32000HZ,
8089           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
8090           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
8091           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
8092           .octets_per_frame = 80};
8093 
8094   bool set_before_media = false;
8095   bool set_while_media = true;
8096   bool is_using_set_before_media_codec_during_media = false;
8097   bool is_using_set_while_media_codec_during_media = false;
8098   // should use legacy codec
8099   bool is_reconfig = false;
8100   TestSetCodecPreference(nullptr, &preferred_codec_config_during_media, LeAudioContextType::MEDIA,
8101                          group_id, set_before_media, set_while_media,
8102                          is_using_set_before_media_codec_during_media,
8103                          is_using_set_while_media_codec_during_media, is_reconfig);
8104 
8105   // simulate suspend timeout passed, alarm executing
8106   fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
8107   SyncOnMainLoop();
8108 
8109   // SetInCall is used by GTBS - and only then we can expect CCID to be set.
8110   LeAudioClient::Get()->SetInCall(true);
8111 
8112   bool set_before_conv = false;
8113   bool set_while_conv = false;
8114   bool is_using_set_before_conv_codec_during_conv = true;
8115   bool is_using_set_while_conv_codec_during_conv = false;
8116   is_reconfig = false;
8117   TestSetCodecPreference(nullptr, nullptr, LeAudioContextType::CONVERSATIONAL, group_id,
8118                          set_before_conv, set_while_conv,
8119                          is_using_set_before_conv_codec_during_conv,
8120                          is_using_set_while_conv_codec_during_conv, is_reconfig);
8121   LeAudioClient::Get()->SetInCall(false);
8122 
8123   // should use legacy codec when switching back to media
8124   ASSERT_EQ(LeAudioClient::Get()->IsUsingPreferredCodecConfig(
8125                     group_id, static_cast<int>(types::LeAudioContextType::MEDIA)),
8126             false);
8127 }
8128 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceWhenMediaNotForBothMediaAndConv)8129 TEST_F(UnicastTest, TwoEarbudsSetPreferenceWhenMediaNotForBothMediaAndConv) {
8130   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
8131 
8132   int group_id = 2;
8133   TestSetupRemoteDevices(group_id);
8134 
8135   // This codec can not be used by media and conv
8136   btle_audio_codec_config_t preferred_codec_config_during_media = {
8137           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
8138           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_24000HZ,
8139           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
8140           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
8141           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
8142           .octets_per_frame = 70};
8143 
8144   bool set_before_media = false;
8145   bool set_while_media = true;
8146   bool is_using_set_before_media_codec_during_media = false;
8147   bool is_using_set_while_media_codec_during_media = false;
8148   // should use legacy codec
8149   bool is_reconfig = false;
8150   TestSetCodecPreference(nullptr, &preferred_codec_config_during_media, LeAudioContextType::MEDIA,
8151                          group_id, set_before_media, set_while_media,
8152                          is_using_set_before_media_codec_during_media,
8153                          is_using_set_while_media_codec_during_media, is_reconfig);
8154 
8155   // simulate suspend timeout passed, alarm executing
8156   fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
8157   SyncOnMainLoop();
8158 
8159   // SetInCall is used by GTBS - and only then we can expect CCID to be set.
8160   LeAudioClient::Get()->SetInCall(true);
8161 
8162   bool set_before_conv = false;
8163   bool set_while_conv = false;
8164   bool is_using_set_before_conv_codec_during_conv = false;
8165   bool is_using_set_while_conv_codec_during_conv = false;
8166   is_reconfig = false;
8167   TestSetCodecPreference(nullptr, nullptr, LeAudioContextType::CONVERSATIONAL, group_id,
8168                          set_before_conv, set_while_conv,
8169                          is_using_set_before_conv_codec_during_conv,
8170                          is_using_set_while_conv_codec_during_conv, is_reconfig);
8171   LeAudioClient::Get()->SetInCall(false);
8172 
8173   // should use legacy codec when switching back to media
8174   ASSERT_EQ(LeAudioClient::Get()->IsUsingPreferredCodecConfig(
8175                     group_id, static_cast<int>(types::LeAudioContextType::MEDIA)),
8176             false);
8177 }
8178 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceWhenConvForBothMediaAndConv)8179 TEST_F(UnicastTest, TwoEarbudsSetPreferenceWhenConvForBothMediaAndConv) {
8180   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
8181 
8182   int group_id = 2;
8183   TestSetupRemoteDevices(group_id);
8184 
8185   bool set_before_media = false;
8186   bool set_while_media = false;
8187   bool is_using_set_before_media_codec_during_media = false;
8188   bool is_using_set_while_media_codec_during_media = false;
8189   bool is_reconfig = false;
8190   TestSetCodecPreference(nullptr, nullptr, LeAudioContextType::MEDIA, group_id, set_before_media,
8191                          set_while_media, is_using_set_before_media_codec_during_media,
8192                          is_using_set_while_media_codec_during_media, is_reconfig);
8193 
8194   // simulate suspend timeout passed, alarm executing
8195   fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
8196   SyncOnMainLoop();
8197 
8198   // This codec can be used by media and conv
8199   btle_audio_codec_config_t preferred_codec_config_during_conv = {
8200           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
8201           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_16000HZ,
8202           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
8203           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
8204           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
8205           .octets_per_frame = 40};
8206 
8207   // SetInCall is used by GTBS - and only then we can expect CCID to be set.
8208   LeAudioClient::Get()->SetInCall(true);
8209 
8210   bool set_before_conv = false;
8211   bool set_while_conv = true;
8212   bool is_using_set_before_conv_codec_during_conv = false;
8213   bool is_using_set_while_conv_codec_during_conv = true;
8214   // should use preferred codec and reconfig
8215   is_reconfig = true;
8216   TestSetCodecPreference(nullptr, &preferred_codec_config_during_conv,
8217                          LeAudioContextType::CONVERSATIONAL, group_id, set_before_conv,
8218                          set_while_conv, is_using_set_before_conv_codec_during_conv,
8219                          is_using_set_while_conv_codec_during_conv, is_reconfig);
8220   LeAudioClient::Get()->SetInCall(false);
8221 
8222   // should use preferred codec when switching back to media
8223   ASSERT_EQ(LeAudioClient::Get()->IsUsingPreferredCodecConfig(
8224                     group_id, static_cast<int>(types::LeAudioContextType::MEDIA)),
8225             true);
8226 }
8227 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceWhenConvForMediaNotForConv)8228 TEST_F(UnicastTest, TwoEarbudsSetPreferenceWhenConvForMediaNotForConv) {
8229   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
8230 
8231   int group_id = 2;
8232   TestSetupRemoteDevices(group_id);
8233 
8234   bool set_before_media = false;
8235   bool set_while_media = false;
8236   bool is_using_set_before_media_codec_during_media = false;
8237   bool is_using_set_while_media_codec_during_media = false;
8238   bool is_reconfig = false;
8239   TestSetCodecPreference(nullptr, nullptr, LeAudioContextType::MEDIA, group_id, set_before_media,
8240                          set_while_media, is_using_set_before_media_codec_during_media,
8241                          is_using_set_while_media_codec_during_media, is_reconfig);
8242 
8243   // simulate suspend timeout passed, alarm executing
8244   fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
8245   SyncOnMainLoop();
8246 
8247   // This codec can be used by media but not by conv
8248   btle_audio_codec_config_t preferred_codec_config_during_conv = {
8249           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
8250           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_24000HZ,
8251           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
8252           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
8253           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
8254           .octets_per_frame = 60};
8255 
8256   // SetInCall is used by GTBS - and only then we can expect CCID to be set.
8257   LeAudioClient::Get()->SetInCall(true);
8258 
8259   bool set_before_conv = false;
8260   bool set_while_conv = true;
8261   bool is_using_set_before_conv_codec_during_conv = false;
8262   bool is_using_set_while_conv_codec_during_conv = false;
8263   // should use legacy codec
8264   is_reconfig = false;
8265   TestSetCodecPreference(nullptr, &preferred_codec_config_during_conv,
8266                          LeAudioContextType::CONVERSATIONAL, group_id, set_before_conv,
8267                          set_while_conv, is_using_set_before_conv_codec_during_conv,
8268                          is_using_set_while_conv_codec_during_conv, is_reconfig);
8269   LeAudioClient::Get()->SetInCall(false);
8270 
8271   // should use preferred codec when switching back to media
8272   ASSERT_EQ(LeAudioClient::Get()->IsUsingPreferredCodecConfig(
8273                     group_id, static_cast<int>(types::LeAudioContextType::MEDIA)),
8274             true);
8275 }
8276 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceWhenConvNotForMediaForConv)8277 TEST_F(UnicastTest, TwoEarbudsSetPreferenceWhenConvNotForMediaForConv) {
8278   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
8279 
8280   int group_id = 2;
8281   TestSetupRemoteDevices(group_id);
8282 
8283   bool set_before_media = false;
8284   bool set_while_media = false;
8285   bool is_using_set_before_media_codec_during_media = false;
8286   bool is_using_set_while_media_codec_during_media = false;
8287   bool is_reconfig = false;
8288   TestSetCodecPreference(nullptr, nullptr, LeAudioContextType::MEDIA, group_id, set_before_media,
8289                          set_while_media, is_using_set_before_media_codec_during_media,
8290                          is_using_set_while_media_codec_during_media, is_reconfig);
8291 
8292   // simulate suspend timeout passed, alarm executing
8293   fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
8294   SyncOnMainLoop();
8295 
8296   // This codec can not be used by media but by conv
8297   btle_audio_codec_config_t preferred_codec_config_during_conv = {
8298           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
8299           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_32000HZ,
8300           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
8301           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
8302           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
8303           .octets_per_frame = 80};
8304 
8305   // SetInCall is used by GTBS - and only then we can expect CCID to be set.
8306   LeAudioClient::Get()->SetInCall(true);
8307 
8308   bool set_before_conv = false;
8309   bool set_while_conv = true;
8310   bool is_using_set_before_conv_codec_during_conv = false;
8311   bool is_using_set_while_conv_codec_during_conv = true;
8312   // should use preferred codec but not reconfig
8313   is_reconfig = false;
8314   TestSetCodecPreference(nullptr, &preferred_codec_config_during_conv,
8315                          LeAudioContextType::CONVERSATIONAL, group_id, set_before_conv,
8316                          set_while_conv, is_using_set_before_conv_codec_during_conv,
8317                          is_using_set_while_conv_codec_during_conv, is_reconfig);
8318   LeAudioClient::Get()->SetInCall(false);
8319 
8320   // should use legacy codec when switching back to media
8321   ASSERT_EQ(LeAudioClient::Get()->IsUsingPreferredCodecConfig(
8322                     group_id, static_cast<int>(types::LeAudioContextType::MEDIA)),
8323             false);
8324 }
8325 
TEST_F(UnicastTest,TwoEarbudsSetPreferenceWhenConvNotForBothMediaAndConv)8326 TEST_F(UnicastTest, TwoEarbudsSetPreferenceWhenConvNotForBothMediaAndConv) {
8327   com::android::bluetooth::flags::provider_->leaudio_set_codec_config_preference(true);
8328 
8329   int group_id = 2;
8330   TestSetupRemoteDevices(group_id);
8331 
8332   bool set_before_media = false;
8333   bool set_while_media = false;
8334   bool is_using_set_before_media_codec_during_media = false;
8335   bool is_using_set_while_media_codec_during_media = false;
8336   bool is_reconfig = false;
8337   TestSetCodecPreference(nullptr, nullptr, LeAudioContextType::MEDIA, group_id, set_before_media,
8338                          set_while_media, is_using_set_before_media_codec_during_media,
8339                          is_using_set_while_media_codec_during_media, is_reconfig);
8340 
8341   // simulate suspend timeout passed, alarm executing
8342   fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
8343   SyncOnMainLoop();
8344 
8345   // This codec can not be used by media and conv
8346   btle_audio_codec_config_t preferred_codec_config_during_conv = {
8347           .codec_type = LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
8348           .sample_rate = LE_AUDIO_SAMPLE_RATE_INDEX_24000HZ,
8349           .bits_per_sample = LE_AUDIO_BITS_PER_SAMPLE_INDEX_16,
8350           .channel_count = LE_AUDIO_CHANNEL_COUNT_INDEX_1,
8351           .frame_duration = LE_AUDIO_FRAME_DURATION_INDEX_10000US,
8352           .octets_per_frame = 70};
8353 
8354   // SetInCall is used by GTBS - and only then we can expect CCID to be set.
8355   LeAudioClient::Get()->SetInCall(true);
8356 
8357   bool set_before_conv = false;
8358   bool set_while_conv = true;
8359   bool is_using_set_before_conv_codec_during_conv = false;
8360   bool is_using_set_while_conv_codec_during_conv = false;
8361   // should use legacy codec
8362   is_reconfig = false;
8363   TestSetCodecPreference(nullptr, &preferred_codec_config_during_conv,
8364                          LeAudioContextType::CONVERSATIONAL, group_id, set_before_conv,
8365                          set_while_conv, is_using_set_before_conv_codec_during_conv,
8366                          is_using_set_while_conv_codec_during_conv, is_reconfig);
8367   LeAudioClient::Get()->SetInCall(false);
8368 
8369   // should use legacy codec when switching back to media
8370   ASSERT_EQ(LeAudioClient::Get()->IsUsingPreferredCodecConfig(
8371                     group_id, static_cast<int>(types::LeAudioContextType::MEDIA)),
8372             false);
8373 }
8374 
TEST_F(UnicastTest,StreamingVxAospSampleSound)8375 TEST_F(UnicastTest, StreamingVxAospSampleSound) {
8376   uint8_t group_size = 2;
8377   int group_id = 2;
8378 
8379   /* Test to verify that tag VX_AOSP_SAMPLESOUND is always mapped to
8380    * LeAudioContextType::SOUNDEFFECTS
8381    */
8382 
8383   // Report working CSIS
8384   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
8385 
8386   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
8387           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
8388 
8389   // First earbud
8390   const RawAddress test_address0 = GetTestAddress(0);
8391   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
8392   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
8393                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
8394 
8395   // Second earbud
8396   const RawAddress test_address1 = GetTestAddress(1);
8397   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
8398   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
8399                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
8400                     true /*connect_through_csis*/);
8401 
8402   // Start streaming
8403   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
8404   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
8405   LeAudioClient::Get()->GroupSetActive(group_id);
8406   SyncOnMainLoop();
8407 
8408   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
8409 
8410   // Set a test TAG
8411   char test_tag[] = "TEST_TAG2;VX_AOSP_SAMPLESOUND;TEST_TAG1";
8412 
8413   test_tags_ptr_ = test_tag;
8414 
8415   auto initial_context = types::LeAudioContextType::SOUNDEFFECTS;
8416   types::BidirectionalPair<std::vector<uint8_t>> ccids = {.sink = {}, .source = {}};
8417   EXPECT_CALL(mock_state_machine_, StartStream(_, initial_context, _, ccids)).Times(1);
8418   StartStreaming(AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_CONTENT_TYPE_SPEECH, group_id);
8419 
8420   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
8421   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
8422   SyncOnMainLoop();
8423 
8424   // Verify Data transfer on two peer sinks and one source
8425   uint8_t cis_count_out = 2;
8426   uint8_t cis_count_in = 0;
8427   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 0);
8428 }
8429 
TEST_F(UnicastTest,UpdateActiveAudioConfigForLocalSinkSource)8430 TEST_F(UnicastTest, UpdateActiveAudioConfigForLocalSinkSource) {
8431   uint8_t group_size = 2;
8432   int group_id = 2;
8433 
8434   // Report working CSIS
8435   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
8436 
8437   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
8438           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
8439 
8440   // First earbud
8441   const RawAddress test_address0 = GetTestAddress(0);
8442   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
8443   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
8444                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
8445 
8446   // Second earbud
8447   const RawAddress test_address1 = GetTestAddress(1);
8448   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
8449   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
8450                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
8451                     true /*connect_through_csis*/);
8452 
8453   // Set group as active
8454   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
8455   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
8456   LeAudioClient::Get()->GroupSetActive(group_id);
8457   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
8458 
8459   // Start streaming - expect HAL being notified by both directions config change
8460   EXPECT_CALL(*mock_le_audio_sink_hal_client_, UpdateAudioConfigToHal(_)).Times(1);
8461   EXPECT_CALL(*mock_le_audio_source_hal_client_, UpdateAudioConfigToHal(_)).Times(1);
8462 
8463   /* Expect one update per direction - 2 in total for voice communication usage */
8464   EXPECT_CALL(*mock_codec_manager_, UpdateActiveAudioConfig(_, _, _))
8465           .WillRepeatedly([&](const types::BidirectionalPair<stream_parameters>& stream_params,
8466                               std::function<void(const stream_config& config, uint8_t direction)>
8467                                       update_receiver,
8468                               uint8_t directions_to_update) {
8469             bluetooth::le_audio::stream_config unicast_cfg;
8470             if ((directions_to_update & bluetooth::le_audio::types::kLeAudioDirectionSink) &&
8471                 stream_params.sink.stream_config.peer_delay_ms != 0) {
8472               update_receiver(unicast_cfg, bluetooth::le_audio::types::kLeAudioDirectionSink);
8473             }
8474             if ((directions_to_update & bluetooth::le_audio::types::kLeAudioDirectionSource) &&
8475                 stream_params.source.stream_config.peer_delay_ms != 0) {
8476               update_receiver(unicast_cfg, bluetooth::le_audio::types::kLeAudioDirectionSource);
8477             }
8478           });
8479   StartStreaming(AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_CONTENT_TYPE_SPEECH, group_id);
8480 
8481   SyncOnMainLoop();
8482   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
8483   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
8484   Mock::VerifyAndClearExpectations(&mock_codec_manager_);
8485 
8486   // Verify Data transfer on two peer sinks and two sources
8487   uint8_t cis_count_out = 2;
8488   uint8_t cis_count_in = 2;
8489   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 40);
8490 
8491   // Suspend
8492   LeAudioClient::Get()->GroupSuspend(group_id);
8493   SyncOnMainLoop();
8494 }
8495 
TEST_F(UnicastTest,UpdateActiveAudioConfigForLocalSinkSourceLateJoin)8496 TEST_F(UnicastTest, UpdateActiveAudioConfigForLocalSinkSourceLateJoin) {
8497   uint8_t group_size = 2;
8498   int group_id = 2;
8499 
8500   // Report working CSIS
8501   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
8502 
8503   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
8504           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
8505 
8506   // First earbud
8507   const RawAddress test_address0 = GetTestAddress(0);
8508   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
8509   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
8510                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
8511 
8512   // Set group as active
8513   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
8514   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
8515   LeAudioClient::Get()->GroupSetActive(group_id);
8516   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
8517 
8518   // Start streaming - expect HAL being notified by both directions config change
8519   EXPECT_CALL(*mock_le_audio_sink_hal_client_, UpdateAudioConfigToHal(_)).Times(1);
8520   EXPECT_CALL(*mock_le_audio_source_hal_client_, UpdateAudioConfigToHal(_)).Times(1);
8521 
8522   /* Expect one update per direction - 2 in total for voice communication usage */
8523   EXPECT_CALL(*mock_codec_manager_, UpdateActiveAudioConfig(_, _, _))
8524           .WillRepeatedly([&](const types::BidirectionalPair<stream_parameters>& stream_params,
8525                               std::function<void(const stream_config& config, uint8_t direction)>
8526                                       update_receiver,
8527                               uint8_t directions_to_update) {
8528             bluetooth::le_audio::stream_config unicast_cfg;
8529             if ((directions_to_update & bluetooth::le_audio::types::kLeAudioDirectionSink) &&
8530                 stream_params.sink.stream_config.peer_delay_ms != 0) {
8531               update_receiver(unicast_cfg, bluetooth::le_audio::types::kLeAudioDirectionSink);
8532             }
8533             if ((directions_to_update & bluetooth::le_audio::types::kLeAudioDirectionSource) &&
8534                 stream_params.source.stream_config.peer_delay_ms != 0) {
8535               update_receiver(unicast_cfg, bluetooth::le_audio::types::kLeAudioDirectionSource);
8536             }
8537           });
8538   StartStreaming(AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_CONTENT_TYPE_SPEECH, group_id);
8539   SyncOnMainLoop();
8540   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
8541   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
8542 
8543   // Second earbud join should trigger audio config update to HAL
8544   EXPECT_CALL(*mock_le_audio_sink_hal_client_, UpdateAudioConfigToHal(_)).Times(1);
8545   EXPECT_CALL(*mock_le_audio_source_hal_client_, UpdateAudioConfigToHal(_)).Times(1);
8546 
8547   const RawAddress test_address1 = GetTestAddress(1);
8548   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
8549   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
8550                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
8551                     true /*connect_through_csis*/);
8552 
8553   SyncOnMainLoop();
8554   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
8555   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
8556   Mock::VerifyAndClearExpectations(&mock_codec_manager_);
8557 
8558   // Verify Data transfer on two peer sinks and two sources
8559   uint8_t cis_count_out = 2;
8560   uint8_t cis_count_in = 2;
8561   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 40);
8562 
8563   SyncOnMainLoop();
8564   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
8565   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
8566 
8567   // Second earbud disconnect should trigger audio config update to HAL
8568   EXPECT_CALL(*mock_le_audio_sink_hal_client_, UpdateAudioConfigToHal(_)).Times(1);
8569   EXPECT_CALL(*mock_le_audio_source_hal_client_, UpdateAudioConfigToHal(_)).Times(1);
8570 
8571   /* Simulate ASE releasing and CIS Disconnection */
8572   ASSERT_NE(0lu, streaming_groups.count(group_id));
8573   auto group = streaming_groups.at(group_id);
8574   ASSERT_NE(group, nullptr);
8575   auto device = group->GetFirstDevice();
8576   for (auto& ase : device->ases_) {
8577     /* Releasing state */
8578     if (!ase.active) {
8579       continue;
8580     }
8581 
8582     std::vector<uint8_t> releasing_state = {
8583             ase.id, static_cast<uint8_t>(types::AseState::BTA_LE_AUDIO_ASE_STATE_RELEASING)};
8584     InjectNotificationEvent(device->address_, device->conn_id_, ase.hdls.val_hdl, releasing_state);
8585     SyncOnMainLoop();
8586     InjectCisDisconnected(group_id, ase.cis_conn_hdl);
8587     SyncOnMainLoop();
8588   }
8589 
8590   SyncOnMainLoop();
8591   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
8592   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
8593   Mock::VerifyAndClearExpectations(&mock_codec_manager_);
8594 
8595   // Suspend
8596   LeAudioClient::Get()->GroupSuspend(group_id);
8597   SyncOnMainLoop();
8598 }
8599 
TEST_F(UnicastTest,UpdateActiveAudioConfigForLocalSource)8600 TEST_F(UnicastTest, UpdateActiveAudioConfigForLocalSource) {
8601   uint8_t group_size = 2;
8602   int group_id = 2;
8603 
8604   // Report working CSIS
8605   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
8606 
8607   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
8608           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
8609 
8610   // First earbud
8611   const RawAddress test_address0 = GetTestAddress(0);
8612   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
8613   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
8614                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
8615 
8616   // Second earbud
8617   const RawAddress test_address1 = GetTestAddress(1);
8618   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
8619   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
8620                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
8621                     true /*connect_through_csis*/);
8622 
8623   // Set group as active
8624   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
8625   LeAudioClient::Get()->GroupSetActive(group_id);
8626   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
8627 
8628   // Start streaming
8629   EXPECT_CALL(*mock_le_audio_source_hal_client_, UpdateAudioConfigToHal(_)).Times(1);
8630   EXPECT_CALL(*mock_le_audio_sink_hal_client_, UpdateAudioConfigToHal(_)).Times(0);
8631   EXPECT_CALL(*mock_codec_manager_, UpdateActiveAudioConfig(_, _, _))
8632           .Times(1)
8633           .WillOnce([](const types::BidirectionalPair<stream_parameters>& stream_params,
8634                        std::function<void(const stream_config& config, uint8_t direction)>
8635                                update_receiver,
8636                        uint8_t directions_to_update) {
8637             bluetooth::le_audio::stream_config unicast_cfg;
8638             if ((directions_to_update & bluetooth::le_audio::types::kLeAudioDirectionSink) &&
8639                 stream_params.sink.stream_config.peer_delay_ms != 0) {
8640               update_receiver(unicast_cfg, bluetooth::le_audio::types::kLeAudioDirectionSink);
8641             }
8642             if ((directions_to_update & bluetooth::le_audio::types::kLeAudioDirectionSource) &&
8643                 stream_params.source.stream_config.peer_delay_ms != 0) {
8644               update_receiver(unicast_cfg, bluetooth::le_audio::types::kLeAudioDirectionSource);
8645             }
8646           });
8647   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
8648 
8649   SyncOnMainLoop();
8650   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
8651   Mock::VerifyAndClearExpectations(&mock_codec_manager_);
8652 
8653   // Verify Data transfer on two peer sinks and no source
8654   uint8_t cis_count_out = 2;
8655   uint8_t cis_count_in = 0;
8656   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 40);
8657 
8658   // Suspend
8659   LeAudioClient::Get()->GroupSuspend(group_id);
8660   SyncOnMainLoop();
8661 }
8662 
TEST_F(UnicastTest,TwoEarbudsStreamingContextSwitchNoReconfigure)8663 TEST_F(UnicastTest, TwoEarbudsStreamingContextSwitchNoReconfigure) {
8664   uint8_t group_size = 2;
8665   int group_id = 2;
8666 
8667   // Report working CSIS
8668   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
8669 
8670   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
8671           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
8672 
8673   // First earbud
8674   const RawAddress test_address0 = GetTestAddress(0);
8675   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
8676   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
8677                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
8678 
8679   // Second earbud
8680   const RawAddress test_address1 = GetTestAddress(1);
8681   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
8682   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
8683                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
8684                     true /*connect_through_csis*/);
8685 
8686   // Start streaming
8687   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
8688   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
8689   LeAudioClient::Get()->GroupSetActive(group_id);
8690   SyncOnMainLoop();
8691   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
8692 
8693   // Start streaming with new metadata, there was no previous stream so start
8694   // with this new configuration
8695   auto initial_context = types::LeAudioContextType::NOTIFICATIONS;
8696   types::BidirectionalPair<types::AudioContexts> contexts = {
8697           .sink = types::AudioContexts(initial_context), .source = types::AudioContexts()};
8698   EXPECT_CALL(mock_state_machine_, StartStream(_, initial_context, contexts, _)).Times(1);
8699 
8700   StartStreaming(AUDIO_USAGE_NOTIFICATION, AUDIO_CONTENT_TYPE_UNKNOWN, group_id);
8701 
8702   SyncOnMainLoop();
8703   Mock::VerifyAndClearExpectations(&mock_state_machine_);
8704   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
8705   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
8706 
8707   // Do a metadata content switch to ALERTS but stay on previous configuration
8708   EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(0);
8709   EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop).Times(0);
8710   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start).Times(0);
8711   contexts = {.sink = types::AudioContexts(types::LeAudioContextType::ALERTS),
8712               .source = types::AudioContexts()};
8713   EXPECT_CALL(mock_state_machine_, StartStream(_, initial_context, contexts, _)).Times(1);
8714   UpdateLocalSourceMetadata(AUDIO_USAGE_ALARM, AUDIO_CONTENT_TYPE_UNKNOWN);
8715 
8716   SyncOnMainLoop();
8717   Mock::VerifyAndClearExpectations(&mock_state_machine_);
8718   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
8719   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
8720 
8721   // Do a metadata content switch to EMERGENCY but stay on previous
8722   // configuration
8723   EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(0);
8724   EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop).Times(0);
8725   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start).Times(0);
8726 
8727   contexts = {.sink = types::AudioContexts(types::LeAudioContextType::EMERGENCYALARM),
8728               .source = types::AudioContexts()};
8729   EXPECT_CALL(mock_state_machine_, StartStream(_, initial_context, contexts, _)).Times(1);
8730   UpdateLocalSourceMetadata(AUDIO_USAGE_EMERGENCY, AUDIO_CONTENT_TYPE_UNKNOWN);
8731 
8732   SyncOnMainLoop();
8733   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
8734   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
8735 
8736   // Do a metadata content switch to INSTRUCTIONAL but stay on previous
8737   // configuration
8738   EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(0);
8739   EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop).Times(0);
8740   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start).Times(0);
8741   contexts = {.sink = types::AudioContexts(types::LeAudioContextType::INSTRUCTIONAL),
8742               .source = types::AudioContexts()};
8743   EXPECT_CALL(mock_state_machine_, StartStream(_, initial_context, contexts, _)).Times(1);
8744   UpdateLocalSourceMetadata(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE, AUDIO_CONTENT_TYPE_UNKNOWN);
8745 
8746   SyncOnMainLoop();
8747   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
8748   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
8749 }
8750 
TEST_F(UnicastTest,TwoEarbudsStopConversational_StartStreamSonification)8751 TEST_F(UnicastTest, TwoEarbudsStopConversational_StartStreamSonification) {
8752   uint8_t group_size = 2;
8753   int group_id = 2;
8754 
8755   // Report working CSIS
8756   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
8757 
8758   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
8759           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
8760 
8761   // First earbud
8762   const RawAddress test_address0 = GetTestAddress(0);
8763   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
8764   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
8765                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
8766 
8767   // Second earbud
8768   const RawAddress test_address1 = GetTestAddress(1);
8769   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
8770   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
8771                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
8772                     true /*connect_through_csis*/);
8773 
8774   // Start streaming
8775   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
8776   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
8777   LeAudioClient::Get()->GroupSetActive(group_id);
8778   SyncOnMainLoop();
8779   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
8780 
8781   // Start streaming with CONVERSATIONAL, there was no previous stream so start
8782   // with this new configuration
8783   auto initial_context = types::LeAudioContextType::CONVERSATIONAL;
8784   types::BidirectionalPair<types::AudioContexts> contexts = {
8785           .sink = types::AudioContexts(initial_context),
8786           .source = types::AudioContexts(initial_context)};
8787   EXPECT_CALL(mock_state_machine_, StartStream(_, initial_context, contexts, _)).Times(1);
8788 
8789   StartStreaming(AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_CONTENT_TYPE_SPEECH, group_id);
8790 
8791   SyncOnMainLoop();
8792   Mock::VerifyAndClearExpectations(&mock_state_machine_);
8793   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
8794   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
8795 
8796   // Stop the stream but KEEP cis UP
8797   StopStreaming(group_id, true);
8798   SyncOnMainLoop();
8799   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
8800 
8801   types::BidirectionalPair<types::AudioContexts> reconfigure_contexts = {
8802           .sink = types::AudioContexts(types::LeAudioContextType::ALERTS),
8803           .source = types::AudioContexts()};
8804 
8805   EXPECT_CALL(mock_state_machine_, StartStream(_, initial_context, reconfigure_contexts, _))
8806           .Times(1);
8807 
8808   // Change context type but expect configuration to by as previous
8809   StartStreaming(AUDIO_USAGE_ALARM, AUDIO_CONTENT_TYPE_UNKNOWN, group_id);
8810 
8811   SyncOnMainLoop();
8812   Mock::VerifyAndClearExpectations(&mock_state_machine_);
8813 
8814   // Stop the stream and drop CISes
8815   StopStreaming(group_id, true);
8816   SyncOnMainLoop();
8817   // simulate suspend timeout passed, alarm executing
8818   fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
8819   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
8820 
8821   auto reconfigure_context = types::LeAudioContextType::ALERTS;
8822 
8823   EXPECT_CALL(mock_state_machine_, StartStream(_, reconfigure_context, reconfigure_contexts, _))
8824           .Times(1);
8825 
8826   // Update metadata
8827   StartStreaming(AUDIO_USAGE_ALARM, AUDIO_CONTENT_TYPE_UNKNOWN, group_id);
8828   SyncOnMainLoop();
8829   Mock::VerifyAndClearExpectations(&mock_state_machine_);
8830 }
8831 
TEST_F(UnicastTest,TwoEarbudsStreamingContextSwitchReconfigure_SpeedUpReconfigFlagEnabled)8832 TEST_F(UnicastTest, TwoEarbudsStreamingContextSwitchReconfigure_SpeedUpReconfigFlagEnabled) {
8833   uint8_t group_size = 2;
8834   int group_id = 2;
8835 
8836   // Report working CSIS
8837   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
8838 
8839   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
8840           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
8841 
8842   // First earbud
8843   const RawAddress test_address0 = GetTestAddress(0);
8844   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
8845   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
8846                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
8847 
8848   // Second earbud
8849   const RawAddress test_address1 = GetTestAddress(1);
8850   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
8851   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
8852                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
8853                     true /*connect_through_csis*/);
8854 
8855   constexpr int gmcs_ccid = 1;
8856   constexpr int gtbs_ccid = 2;
8857 
8858   log::info("Start streaming MEDIA");
8859   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
8860   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
8861   LeAudioClient::Get()->SetCcidInformation(gmcs_ccid, 4 /* Media */);
8862   LeAudioClient::Get()->SetCcidInformation(gtbs_ccid, 2 /* Phone */);
8863   LeAudioClient::Get()->GroupSetActive(group_id);
8864   SyncOnMainLoop();
8865 
8866   types::BidirectionalPair<std::vector<uint8_t>> ccids = {.sink = {gmcs_ccid}, .source = {}};
8867   EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, ccids)).Times(1);
8868   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
8869 
8870   SyncOnMainLoop();
8871   Mock::VerifyAndClearExpectations(&mock_state_machine_);
8872   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
8873   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
8874 
8875   // Verify Data transfer on two peer sinks
8876   uint8_t cis_count_out = 2;
8877   uint8_t cis_count_in = 0;
8878   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
8879 
8880   log::info("Simulate incoming call");
8881 
8882   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(1);
8883   Expectation reconfigure =
8884           EXPECT_CALL(*mock_le_audio_source_hal_client_, SuspendedForReconfiguration()).Times(1);
8885   EXPECT_CALL(*mock_le_audio_source_hal_client_, CancelStreamingRequest()).Times(1);
8886   EXPECT_CALL(*mock_le_audio_source_hal_client_, ReconfigurationComplete())
8887           .Times(1)
8888           .After(reconfigure);
8889   EXPECT_CALL(mock_state_machine_, ConfigureStream(_, _, _, _, _)).Times(1);
8890   // SetInCall is used by GTBS - and only then we can expect CCID to be set.
8891   LeAudioClient::Get()->SetInCall(true);
8892   SyncOnMainLoop();
8893   Mock::VerifyAndClearExpectations(&mock_state_machine_);
8894   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
8895 
8896   // Conversational is a bidirectional scenario so expect GTBS CCID
8897   // in the metadata for both directions. Can be called twice when one
8898   // direction resume after the other and metadata is updated.
8899   ccids = {.sink = {gtbs_ccid}, .source = {gtbs_ccid}};
8900   EXPECT_CALL(mock_state_machine_,
8901               StartStream(_, types::LeAudioContextType::CONVERSATIONAL, _, ccids))
8902           .Times(AtLeast(1));
8903   StartStreaming(AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_CONTENT_TYPE_SPEECH, group_id);
8904 
8905   SyncOnMainLoop();
8906   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
8907   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
8908 
8909   // Verify Data transfer on two peer sinks and one source
8910   cis_count_out = 2;
8911   cis_count_in = 2;
8912   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 40);
8913 
8914   Mock::VerifyAndClearExpectations(&mock_state_machine_);
8915 
8916   // Stop stream will be called by SetInCall
8917   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(1);
8918   reconfigure =
8919           EXPECT_CALL(*mock_le_audio_source_hal_client_, SuspendedForReconfiguration()).Times(1);
8920   EXPECT_CALL(*mock_le_audio_source_hal_client_, CancelStreamingRequest()).Times(1);
8921   EXPECT_CALL(*mock_le_audio_source_hal_client_, ReconfigurationComplete())
8922           .Times(1)
8923           .After(reconfigure);
8924   EXPECT_CALL(mock_state_machine_, ConfigureStream(_, _, _, _, _)).Times(1);
8925 
8926   LeAudioClient::Get()->SetInCall(false);
8927   SyncOnMainLoop();
8928 
8929   Mock::VerifyAndClearExpectations(&mock_state_machine_);
8930   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
8931 
8932   log::info("Switch back to media");
8933 
8934   ccids = {.sink = {gmcs_ccid}, .source = {}};
8935   types::BidirectionalPair<types::AudioContexts> contexts = {
8936           .sink = types::AudioContexts(types::LeAudioContextType::MEDIA),
8937           .source = types::AudioContexts()};
8938   EXPECT_CALL(mock_state_machine_,
8939               ConfigureStream(_, bluetooth::le_audio::types::LeAudioContextType::MEDIA, contexts,
8940                               ccids, _))
8941           .Times(0);
8942   EXPECT_CALL(
8943           mock_state_machine_,
8944           StartStream(_, bluetooth::le_audio::types::LeAudioContextType::MEDIA, contexts, ccids))
8945           .Times(1);
8946   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id, AUDIO_SOURCE_INVALID,
8947                  false);
8948 
8949   SyncOnMainLoop();
8950   Mock::VerifyAndClearExpectations(&mock_state_machine_);
8951   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
8952   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
8953 }
8954 
TEST_F(UnicastTest,TwoEarbudsVoipStreamingVerifyMetadataUpdate)8955 TEST_F(UnicastTest, TwoEarbudsVoipStreamingVerifyMetadataUpdate) {
8956   uint8_t group_size = 2;
8957   int group_id = 2;
8958 
8959   /*
8960    * Scenario
8961    * 1. Configure stream for the VOIP
8962    * 2. Verify CONVERSATIONAL metadata and context is used.
8963    * 3. Resume LocalSink
8964    * 4. Make sure there is no change of the metadata and context
8965    */
8966 
8967   // Report working CSIS
8968   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
8969 
8970   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
8971           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
8972 
8973   // First earbud
8974   const RawAddress test_address0 = GetTestAddress(0);
8975   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
8976   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
8977                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
8978 
8979   // Second earbud
8980   const RawAddress test_address1 = GetTestAddress(1);
8981   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
8982   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
8983                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
8984                     true /*connect_through_csis*/);
8985 
8986   constexpr int gtbs_ccid = 2;
8987 
8988   LeAudioClient::Get()->SetCcidInformation(gtbs_ccid, 2 /* Phone */);
8989   LeAudioClient::Get()->GroupSetActive(group_id);
8990   SyncOnMainLoop();
8991 
8992   // VOIP not using Telecom API has no ccids.
8993   types::BidirectionalPair<std::vector<uint8_t>> ccids = {.sink = {}, .source = {}};
8994   EXPECT_CALL(mock_state_machine_,
8995               StartStream(_, types::LeAudioContextType::CONVERSATIONAL, _, ccids))
8996           .Times(AtLeast(1));
8997 
8998   UpdateLocalSourceMetadata(AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_CONTENT_TYPE_SPEECH);
8999   UpdateLocalSinkMetadata(AUDIO_SOURCE_MIC);
9000 
9001   LocalAudioSourceResume();
9002   SyncOnMainLoop();
9003   Mock::VerifyAndClearExpectations(&mock_state_machine_);
9004 
9005   SyncOnMainLoop();
9006   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
9007   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
9008 
9009   // Verify Data transfer are sending. The LocalSink is not yet resumed.
9010   uint8_t cis_count_out = 2;
9011   uint8_t cis_count_in = 0;
9012   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 0);
9013 
9014   types::BidirectionalPair<types::AudioContexts> contexts = {
9015           .sink = types::AudioContexts(types::LeAudioContextType::CONVERSATIONAL),
9016           .source = types::AudioContexts(types::LeAudioContextType::CONVERSATIONAL)};
9017   EXPECT_CALL(mock_state_machine_,
9018               StartStream(_, types::LeAudioContextType::CONVERSATIONAL, contexts, ccids))
9019           .Times(AtLeast(1));
9020 
9021   LocalAudioSinkResume();
9022   SyncOnMainLoop();
9023   Mock::VerifyAndClearExpectations(&mock_state_machine_);
9024 }
9025 
TEST_F(UnicastTest,TwoEarbudsVoipDuringLiveVerifyMetadataUpdate)9026 TEST_F(UnicastTest, TwoEarbudsVoipDuringLiveVerifyMetadataUpdate) {
9027   uint8_t group_size = 2;
9028   int group_id = 2;
9029 
9030   /*
9031    * Scenario
9032    * 1. Configure stream for the mixed CONVERSATIONAL and MEDIA
9033    * 2. Start and Stop streaming
9034    * 3. Update CONVERSATIONAL metadata with additional LIVE usage for the mixed contexts
9035    * 4. Resume LocalSink and LocalSource
9036    * 5. Make sure there is only the leading CONVERSATIONAL context in the metadata and
9037    *    LIVE is not mixed in, as the remote devices often are confused when any other
9038    *    bidirectional audio context is mixed with CONVERSATIONAL
9039    */
9040 
9041   // Report working CSIS
9042   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
9043 
9044   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
9045           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
9046 
9047   available_snk_context_types_ =
9048           (types::LeAudioContextType::CONVERSATIONAL | types::LeAudioContextType::MEDIA |
9049            types::LeAudioContextType::LIVE)
9050                   .value();
9051   available_src_context_types_ = available_snk_context_types_;
9052 
9053   // First earbud
9054   const RawAddress test_address0 = GetTestAddress(0);
9055   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
9056   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
9057                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
9058 
9059   // Second earbud
9060   const RawAddress test_address1 = GetTestAddress(1);
9061   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
9062   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
9063                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
9064                     true /*connect_through_csis*/);
9065 
9066   constexpr int gtbs_ccid = 2;
9067 
9068   LeAudioClient::Get()->SetCcidInformation(gtbs_ccid, 2 /* Phone */);
9069   LeAudioClient::Get()->GroupSetActive(group_id);
9070   SyncOnMainLoop();
9071 
9072   StartStreaming(AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_CONTENT_TYPE_MUSIC, group_id);
9073   StopStreaming(group_id);
9074 
9075   // Add LIVE into the mix but expect staying with CONVERSATIONAL for the configuration and the
9076   // metadata
9077   types::BidirectionalPair<types::AudioContexts> meta_contexts = {
9078           .sink = types::AudioContexts(types::LeAudioContextType::CONVERSATIONAL),
9079           .source = types::AudioContexts(types::LeAudioContextType::CONVERSATIONAL)};
9080   EXPECT_CALL(mock_state_machine_,
9081               StartStream(_, types::LeAudioContextType::CONVERSATIONAL, meta_contexts, _))
9082           .Times(AtLeast(1));
9083 
9084   UpdateLocalSinkMetadata(AUDIO_SOURCE_MIC, AUDIO_SOURCE_VOICE_COMMUNICATION);
9085   UpdateLocalSourceMetadata(AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_CONTENT_TYPE_SPEECH, false);
9086   SyncOnMainLoop();
9087 
9088   LocalAudioSourceResume();
9089   LocalAudioSinkResume();
9090 
9091   Mock::VerifyAndClearExpectations(&mock_state_machine_);
9092   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
9093   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
9094 }
9095 
TEST_F(UnicastTest,TwoReconfigureAndVerifyEnableContextType)9096 TEST_F(UnicastTest, TwoReconfigureAndVerifyEnableContextType) {
9097   uint8_t group_size = 2;
9098   int group_id = 2;
9099 
9100   /* Scenario
9101    * 1. Earbuds streaming MEDIA
9102    * 2. Reconfigure to VOIP
9103    * 3. Check if Metadata in Enable command are set to CONVERSATIONAL
9104    */
9105 
9106   // Report working CSIS
9107   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
9108 
9109   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
9110           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
9111 
9112   // First earbud
9113   const RawAddress test_address0 = GetTestAddress(0);
9114   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
9115   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
9116                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
9117 
9118   // Second earbud
9119   const RawAddress test_address1 = GetTestAddress(1);
9120   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
9121   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
9122                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
9123                     true /*connect_through_csis*/);
9124 
9125   constexpr int gmcs_ccid = 1;
9126   constexpr int gtbs_ccid = 2;
9127 
9128   // Start streaming MEDIA
9129   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
9130   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
9131   LeAudioClient::Get()->SetCcidInformation(gmcs_ccid, 4 /* Media */);
9132   LeAudioClient::Get()->SetCcidInformation(gtbs_ccid, 2 /* Phone */);
9133   LeAudioClient::Get()->GroupSetActive(group_id);
9134   SyncOnMainLoop();
9135 
9136   types::BidirectionalPair<std::vector<uint8_t>> ccids = {.sink = {gmcs_ccid}, .source = {}};
9137   EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, ccids)).Times(1);
9138   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
9139 
9140   SyncOnMainLoop();
9141   Mock::VerifyAndClearExpectations(&mock_state_machine_);
9142   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
9143   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
9144 
9145   // Verify Data transfer on two peer sinks
9146   uint8_t cis_count_out = 2;
9147   uint8_t cis_count_in = 0;
9148   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
9149 
9150   // Conversational is a bidirectional scenario so expect GTBS CCID
9151   // in the metadata for both directions. Can be called twice when one
9152   // direction resume after the other and metadata is updated.
9153   ccids = {.sink = {gtbs_ccid}, .source = {gtbs_ccid}};
9154   types::BidirectionalPair<types::AudioContexts> conversiational_contexts = {
9155           .sink = types::AudioContexts(types::LeAudioContextType::CONVERSATIONAL),
9156           .source = types::AudioContexts(types::LeAudioContextType::CONVERSATIONAL)};
9157 
9158   EXPECT_CALL(mock_state_machine_,
9159               ConfigureStream(_, types::LeAudioContextType::CONVERSATIONAL, _, _, _))
9160           .Times(AtLeast(1));
9161 
9162   // Update metadata and resume
9163   UpdateLocalSourceMetadata(AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_CONTENT_TYPE_SPEECH, true);
9164   SyncOnMainLoop();
9165 
9166   Mock::VerifyAndClearExpectations(&mock_state_machine_);
9167   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
9168   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
9169 
9170   EXPECT_CALL(mock_state_machine_, StartStream(_, types::LeAudioContextType::CONVERSATIONAL,
9171                                                conversiational_contexts, ccids))
9172           .Times(AtLeast(1));
9173 
9174   LeAudioClient::Get()->SetInCall(true);
9175 
9176   LocalAudioSourceResume(true);
9177   SyncOnMainLoop();
9178 
9179   Mock::VerifyAndClearExpectations(&mock_state_machine_);
9180 }
9181 
TEST_F(UnicastTest,TwoEarbuds2ndLateConnect)9182 TEST_F(UnicastTest, TwoEarbuds2ndLateConnect) {
9183   uint8_t group_size = 2;
9184   int group_id = 2;
9185 
9186   // Report working CSIS
9187   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
9188 
9189   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
9190           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
9191 
9192   const RawAddress test_address0 = GetTestAddress(0);
9193   const RawAddress test_address1 = GetTestAddress(1);
9194 
9195   // First earbud
9196   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
9197                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
9198 
9199   // Start streaming
9200   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
9201   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
9202   LeAudioClient::Get()->GroupSetActive(group_id);
9203   SyncOnMainLoop();
9204 
9205   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
9206 
9207   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
9208   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
9209   SyncOnMainLoop();
9210 
9211   // Expect one iso channel to be fed with data
9212   uint8_t cis_count_out = 1;
9213   uint8_t cis_count_in = 0;
9214   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
9215 
9216   // Second earbud connects during stream
9217   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
9218                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
9219                     true /*connect_through_csis*/);
9220 
9221   cis_count_out = 2;
9222   cis_count_in = 0;
9223 
9224   /* The above will trigger reconfiguration. After that Audio Hal action
9225    * is needed to restart the stream */
9226   LocalAudioSourceResume();
9227 
9228   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
9229 }
9230 
TEST_F(UnicastTest,TestStreamingContextTypeBehaviour)9231 TEST_F(UnicastTest, TestStreamingContextTypeBehaviour) {
9232   uint8_t group_size = 2;
9233   int group_id = 2;
9234   int conn_id_1 = 1;
9235   int conn_id_2 = 2;
9236 
9237   /* Scenario
9238    * 1. Connect Set of devices with all the context types available
9239    * 2. Create stream for Media
9240    * 3. Remote devices removes all the Available Contexts but UNSPECIFIED
9241    * 4. Verify GetAvailableContexts() returns accepted MEDIA and UNSPECIFIED
9242    */
9243 
9244   // Report working CSIS
9245   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
9246 
9247   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
9248           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
9249 
9250   const RawAddress test_address0 = GetTestAddress(0);
9251   const RawAddress test_address1 = GetTestAddress(1);
9252 
9253   // First earbud connects
9254   ConnectCsisDevice(test_address0, conn_id_1, codec_spec_conf::kLeAudioLocationFrontLeft,
9255                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
9256 
9257   // Second earbud connects
9258   ConnectCsisDevice(test_address1, conn_id_2, codec_spec_conf::kLeAudioLocationFrontRight,
9259                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
9260                     true /*connect_through_csis*/);
9261 
9262   // Start streaming
9263   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
9264   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
9265   LeAudioClient::Get()->GroupSetActive(group_id);
9266   SyncOnMainLoop();
9267 
9268   EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, _)).Times(1);
9269   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
9270   SyncOnMainLoop();
9271   Mock::VerifyAndClearExpectations(&mock_state_machine_);
9272 
9273   auto group = streaming_groups.at(group_id);
9274 
9275   /* Simulate available context type being cleared */
9276   InjectAvailableContextTypes(test_address0, conn_id_1,
9277                               types::AudioContexts(LeAudioContextType::UNSPECIFIED),
9278                               types::AudioContexts(LeAudioContextType::UNSPECIFIED));
9279   InjectAvailableContextTypes(test_address1, conn_id_2,
9280                               types::AudioContexts(LeAudioContextType::UNSPECIFIED),
9281                               types::AudioContexts(LeAudioContextType::UNSPECIFIED));
9282 
9283   auto remote_sink_contexts =
9284           group->GetAvailableContexts(bluetooth::le_audio::types::kLeAudioDirectionSink);
9285   auto remote_source_contexts =
9286           group->GetAvailableContexts(bluetooth::le_audio::types::kLeAudioDirectionSource);
9287   ASSERT_EQ(remote_sink_contexts,
9288             types::AudioContexts(LeAudioContextType::MEDIA | LeAudioContextType::UNSPECIFIED));
9289   ASSERT_EQ(remote_source_contexts, types::AudioContexts(LeAudioContextType::UNSPECIFIED));
9290 }
9291 
TEST_F(UnicastTest,LateStreamConnectBasedOnContextType)9292 TEST_F(UnicastTest, LateStreamConnectBasedOnContextType) {
9293   uint8_t group_size = 2;
9294   int group_id = 2;
9295 
9296   /* Scenario
9297    * 1. Two devices A and B are connect. Device A has all available context
9298    * types, Device B has no available context types.
9299    * 2. Stream creation to Device A has been started
9300    * 3. Device B notified us with new available Context Types - while A is not
9301    * yet streaming
9302    * 4. Make sure AttachToStream was called for Device B
9303    */
9304 
9305   // Report working CSIS
9306   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
9307 
9308   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
9309           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
9310 
9311   const RawAddress test_address0 = GetTestAddress(0);
9312   const RawAddress test_address1 = GetTestAddress(1);
9313 
9314   // First earbud connects
9315   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
9316                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
9317 
9318   // Second earbud connects
9319   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
9320                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
9321                     true /*connect_through_csis*/);
9322 
9323   // Start streaming
9324   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
9325   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
9326   LeAudioClient::Get()->GroupSetActive(group_id);
9327   SyncOnMainLoop();
9328 
9329   /* Simulate available context type being cleared */
9330   InjectAvailableContextTypes(test_address1, 2, types::AudioContexts(0), types::AudioContexts(0));
9331 
9332   // Block streaming state
9333   stay_at_qos_config_in_start_stream = true;
9334 
9335   UpdateLocalSourceMetadata(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC);
9336   LocalAudioSourceResume(false);
9337 
9338   SyncOnMainLoop();
9339   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
9340 
9341   InjectAvailableContextTypes(test_address1, 2, types::kLeAudioContextAllRemoteSinkOnly,
9342                               types::AudioContexts(0), false);
9343 
9344   // Now simulate group is finally streaming
9345   auto group = streaming_groups.at(group_id);
9346   do_in_main_thread(base::BindOnce(
9347           [](int group_id,
9348              bluetooth::le_audio::LeAudioGroupStateMachine::Callbacks* state_machine_callbacks,
9349              LeAudioDeviceGroup* group) {
9350             group->SetState(types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
9351 
9352             state_machine_callbacks->StatusReportCb(group_id, GroupStreamStatus::STREAMING);
9353           },
9354           group_id, base::Unretained(this->state_machine_callbacks_), std::move(group)));
9355 
9356   SyncOnMainLoop();
9357 
9358   /* verify AttachToStream was called while stream was not yet created. */
9359   ASSERT_TRUE(attach_to_stream_scheduled);
9360 
9361   // Expect two iso channel to be fed with data
9362   uint8_t cis_count_out = 2;
9363   uint8_t cis_count_in = 0;
9364   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
9365   SyncOnMainLoop();
9366 }
9367 
TEST_F(UnicastTest,LateStreamConnectBasedOnContextTypeNotFullyConnected)9368 TEST_F(UnicastTest, LateStreamConnectBasedOnContextTypeNotFullyConnected) {
9369   uint8_t group_size = 2;
9370   int group_id = 2;
9371 
9372   /* Scenario
9373    * 1. Device A is connected
9374    * 2. Stream creation to Device A has been started
9375    * 3. Stream is stopped
9376    * 4. Device B is connected but has ongoing operations of available context types read.
9377    * 5. Device B sends available context type  read response
9378    * 6. Make sure AttachToStream was NOT called for Device B since it is not in a CONNECTED state
9379    * yet
9380    */
9381 
9382   // Report working CSIS
9383   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
9384 
9385   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
9386           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
9387 
9388   const RawAddress test_address0 = GetTestAddress(0);
9389   const RawAddress test_address1 = GetTestAddress(1);
9390 
9391   // First earbud connects
9392   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
9393                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
9394   // Start streaming
9395   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
9396   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
9397   LeAudioClient::Get()->GroupSetActive(group_id);
9398   SyncOnMainLoop();
9399 
9400   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
9401   auto group = streaming_groups.at(group_id);
9402 
9403   // Stop streaming - simulate suspend timeout passed, alarm executing
9404   StopStreaming(group_id);
9405   fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
9406   SyncOnMainLoop();
9407 
9408   // Second earbud connects and is set to Getting Ready state
9409   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
9410                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
9411                     true /*connect_through_csis*/);
9412   auto device1 = group->GetNextDevice(group->GetFirstDevice());
9413   device1->SetConnectionState(DeviceConnectState::CONNECTED_AUTOCONNECT_GETTING_READY);
9414 
9415   // Resume but block the final streaming state - keep the group in transition
9416   stay_at_qos_config_in_start_stream = true;
9417   UpdateLocalSourceMetadata(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC);
9418   LocalAudioSourceResume(false);
9419 
9420   // Do not expect to attach the device on context update as it is not fully connected
9421   EXPECT_CALL(mock_state_machine_, AttachToStream(_, _, _)).Times(0);
9422   InjectAvailableContextTypes(test_address1, 2, types::kLeAudioContextAllRemoteSinkOnly,
9423                               types::AudioContexts(0), false);
9424 
9425   Mock::VerifyAndClearExpectations(&mock_state_machine_);
9426   SyncOnMainLoop();
9427 }
9428 
TEST_F(UnicastTest,CheckDeviceIsNotAttachedToStreamWhenNotNeeded)9429 TEST_F(UnicastTest, CheckDeviceIsNotAttachedToStreamWhenNotNeeded) {
9430   uint8_t group_size = 2;
9431   int group_id = 2;
9432 
9433   /* Scenario
9434    * 1. Two devices A and B are connect. Both Devices have all available
9435    * contexts types
9436    * 2. Stream creation to Device A and B has been started
9437    * 3. Device B notified us with new available Context Types - while Group is
9438    * not yet streaming
9439    * 4. Make sure AttachToStream was not called for Device B since it is taking
9440    * part in Stream creation already
9441    */
9442 
9443   // Report working CSIS
9444   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
9445 
9446   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
9447           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
9448 
9449   const RawAddress test_address0 = GetTestAddress(0);
9450   const RawAddress test_address1 = GetTestAddress(1);
9451 
9452   // First earbud connects
9453   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
9454                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
9455 
9456   // Second earbud connects
9457   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
9458                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
9459                     true /*connect_through_csis*/);
9460 
9461   // Start streaming
9462   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
9463   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
9464   LeAudioClient::Get()->GroupSetActive(group_id);
9465   SyncOnMainLoop();
9466 
9467   // Block streaming state
9468   stay_at_qos_config_in_start_stream = true;
9469 
9470   UpdateLocalSourceMetadata(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC);
9471   LocalAudioSourceResume(false);
9472 
9473   SyncOnMainLoop();
9474   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
9475 
9476   InjectAvailableContextTypes(test_address1, 2, types::kLeAudioContextAllRemoteSinkOnly,
9477                               types::AudioContexts(0), false);
9478 
9479   // Now simulate group is finally streaming
9480   auto group = streaming_groups.at(group_id);
9481   do_in_main_thread(base::BindOnce(
9482           [](int group_id,
9483              bluetooth::le_audio::LeAudioGroupStateMachine::Callbacks* state_machine_callbacks,
9484              LeAudioDeviceGroup* group) {
9485             group->SetState(types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
9486 
9487             state_machine_callbacks->StatusReportCb(group_id, GroupStreamStatus::STREAMING);
9488           },
9489           group_id, base::Unretained(this->state_machine_callbacks_), std::move(group)));
9490 
9491   SyncOnMainLoop();
9492 
9493   /* verify AttachToStream was NOT called while stream was not yet created. */
9494   ASSERT_FALSE(attach_to_stream_scheduled);
9495 
9496   // Expect two iso channel to be fed with data
9497   uint8_t cis_count_out = 2;
9498   uint8_t cis_count_in = 0;
9499   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
9500   SyncOnMainLoop();
9501 }
9502 
TEST_F(UnicastTest,ReconnectedDeviceAndAttachedToStreamBecauseOfAvailableContextTypeChange)9503 TEST_F(UnicastTest, ReconnectedDeviceAndAttachedToStreamBecauseOfAvailableContextTypeChange) {
9504   com::android::bluetooth::flags::provider_->le_ase_read_multiple_variable(true);
9505 
9506   uint8_t group_size = 2;
9507   int group_id = 2;
9508 
9509   /* Scenario
9510    * 1. Two devices A and B are streaming
9511    * 2. Device A Release ASE and removes all available context types
9512    * 3. Device B keeps streaming
9513    * 4. Device A disconnectes
9514    * 5. Device A reconnect
9515    * 6. Device A has context available for streaming  and should be attached to the stream
9516    */
9517 
9518   // Report working CSIS
9519   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
9520 
9521   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
9522           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
9523 
9524   const RawAddress test_address0 = GetTestAddress(0);
9525   const RawAddress test_address1 = GetTestAddress(1);
9526 
9527   // First earbud connects
9528   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
9529                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
9530 
9531   // Second earbud connects
9532   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
9533                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
9534                     true /*connect_through_csis*/);
9535 
9536   // Start streaming
9537   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
9538   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
9539   LeAudioClient::Get()->GroupSetActive(group_id);
9540   SyncOnMainLoop();
9541 
9542   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
9543 
9544   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
9545   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
9546   SyncOnMainLoop();
9547 
9548   // Expect two iso channel to be fed with data
9549   uint8_t cis_count_out = 2;
9550   uint8_t cis_count_in = 0;
9551   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
9552 
9553   /* Get group and Device A */
9554   ASSERT_NE(0lu, streaming_groups.count(group_id));
9555   auto group = streaming_groups.at(group_id);
9556   ASSERT_NE(group, nullptr);
9557   auto device = group->GetFirstDevice();
9558 
9559   /* Simulate available context type being cleared */
9560   InjectAvailableContextTypes(device->address_, device->conn_id_, types::AudioContexts(0),
9561                               types::AudioContexts(0));
9562 
9563   /* Simulate ASE releasing and CIS Disconnection */
9564   for (auto& ase : device->ases_) {
9565     /* Releasing state */
9566     if (!ase.active) {
9567       continue;
9568     }
9569 
9570     std::vector<uint8_t> releasing_state = {
9571             ase.id, static_cast<uint8_t>(types::AseState::BTA_LE_AUDIO_ASE_STATE_RELEASING)};
9572     InjectNotificationEvent(device->address_, device->conn_id_, ase.hdls.val_hdl, releasing_state);
9573     SyncOnMainLoop();
9574     InjectCisDisconnected(group_id, ase.cis_conn_hdl);
9575     SyncOnMainLoop();
9576   }
9577 
9578   cis_count_out = 1;
9579   cis_count_in = 0;
9580   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
9581 
9582   /* Device A will disconnect, and do not reconnect automatically */
9583   ON_CALL(mock_gatt_interface_, Open(_, device->address_, BTM_BLE_DIRECT_CONNECTION, _))
9584           .WillByDefault(Return());
9585 
9586   /* Disconnect first device */
9587   auto conn_id = device->conn_id_;
9588   InjectDisconnectedEvent(conn_id, GATT_CONN_TERMINATE_PEER_USER);
9589   SyncOnMainLoop();
9590 
9591   /* For background connect, test needs to Inject Connected Event.
9592    * Note that initial available_snk_context_types_ available_src_context_types_ will
9593    * be read after reconnection, which should bring device to the stream again. */
9594 
9595   InjectConnectedEvent(device->address_, conn_id);
9596   SyncOnMainLoop();
9597 
9598   /* Check single device is streaming */
9599   cis_count_out = 2;
9600   cis_count_in = 0;
9601   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
9602 }
9603 
TEST_F(UnicastTest,ReconnectedDeviceNotAttachedToStreamBecauseOfNotAvailableContext)9604 TEST_F(UnicastTest, ReconnectedDeviceNotAttachedToStreamBecauseOfNotAvailableContext) {
9605   uint8_t group_size = 2;
9606   int group_id = 2;
9607 
9608   /* Scenario
9609    * 1. Two devices A and B are streaming
9610    * 2. Device A Release ASE and removes all available context types
9611    * 3. Device B keeps streaming
9612    * 4. Device A disconnectes
9613    * 5. Device A reconnect and should not be attached to the stream
9614    */
9615 
9616   // Report working CSIS
9617   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
9618 
9619   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
9620           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
9621 
9622   const RawAddress test_address0 = GetTestAddress(0);
9623   const RawAddress test_address1 = GetTestAddress(1);
9624 
9625   // First earbud connects
9626   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
9627                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
9628 
9629   // Second earbud connects
9630   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
9631                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
9632                     true /*connect_through_csis*/);
9633 
9634   // Start streaming
9635   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
9636   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
9637   LeAudioClient::Get()->GroupSetActive(group_id);
9638   SyncOnMainLoop();
9639 
9640   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
9641 
9642   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
9643   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
9644   SyncOnMainLoop();
9645 
9646   // Expect two iso channel to be fed with data
9647   uint8_t cis_count_out = 2;
9648   uint8_t cis_count_in = 0;
9649   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
9650 
9651   /* Get group and Device A */
9652   ASSERT_NE(0lu, streaming_groups.count(group_id));
9653   auto group = streaming_groups.at(group_id);
9654   ASSERT_NE(group, nullptr);
9655   auto device = group->GetFirstDevice();
9656 
9657   /* Simulate available context type being cleared */
9658   InjectAvailableContextTypes(device->address_, device->conn_id_, types::AudioContexts(0),
9659                               types::AudioContexts(0));
9660 
9661   /* Simulate ASE releasing and CIS Disconnection */
9662   for (auto& ase : device->ases_) {
9663     /* Releasing state */
9664     if (!ase.active) {
9665       continue;
9666     }
9667 
9668     std::vector<uint8_t> releasing_state = {
9669             ase.id, static_cast<uint8_t>(types::AseState::BTA_LE_AUDIO_ASE_STATE_RELEASING)};
9670     InjectNotificationEvent(device->address_, device->conn_id_, ase.hdls.val_hdl, releasing_state);
9671     SyncOnMainLoop();
9672     InjectCisDisconnected(group_id, ase.cis_conn_hdl);
9673     SyncOnMainLoop();
9674   }
9675 
9676   cis_count_out = 1;
9677   cis_count_in = 0;
9678   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
9679 
9680   /* Device A will disconnect, and do not reconnect automatically */
9681   ON_CALL(mock_gatt_interface_, Open(_, device->address_, BTM_BLE_DIRECT_CONNECTION, _))
9682           .WillByDefault(Return());
9683 
9684   /* Disconnect first device */
9685   auto conn_id = device->conn_id_;
9686   InjectDisconnectedEvent(conn_id, GATT_CONN_TERMINATE_PEER_USER);
9687   SyncOnMainLoop();
9688 
9689   /* For background connect, test needs to Inject Connected Event.
9690    * Since after reconnect Android reads available context types, make sure
9691    * 0 is read */
9692   available_snk_context_types_ = 0;
9693   available_src_context_types_ = 0;
9694 
9695   InjectConnectedEvent(device->address_, conn_id);
9696   SyncOnMainLoop();
9697 
9698   /* Check single device is streaming */
9699   cis_count_out = 1;
9700   cis_count_in = 0;
9701   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
9702 }
9703 
TEST_F(UnicastTest,TwoEarbuds2ndReleaseAseRemoveAvailableContextAndBack)9704 TEST_F(UnicastTest, TwoEarbuds2ndReleaseAseRemoveAvailableContextAndBack) {
9705   uint8_t group_size = 2;
9706   int group_id = 2;
9707 
9708   /* Scenario
9709    * 1. Two devices A and B are streaming
9710    * 2. Device A Release ASE and removes all available context types
9711    * 3. Device B keeps streaming
9712    * 4. Device A sets available context types
9713    * 5. Device A should be attached to the stream
9714    */
9715 
9716   // Report working CSIS
9717   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
9718 
9719   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
9720           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
9721 
9722   const RawAddress test_address0 = GetTestAddress(0);
9723   const RawAddress test_address1 = GetTestAddress(1);
9724 
9725   // First earbud connects
9726   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
9727                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
9728 
9729   // Second earbud connects
9730   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
9731                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
9732                     true /*connect_through_csis*/);
9733 
9734   // Start streaming
9735   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
9736   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
9737   LeAudioClient::Get()->GroupSetActive(group_id);
9738   SyncOnMainLoop();
9739 
9740   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
9741 
9742   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
9743   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
9744   SyncOnMainLoop();
9745 
9746   // Expect two iso channel to be fed with data
9747   uint8_t cis_count_out = 2;
9748   uint8_t cis_count_in = 0;
9749   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
9750 
9751   /* Get group and Device A */
9752   ASSERT_NE(0lu, streaming_groups.count(group_id));
9753   auto group = streaming_groups.at(group_id);
9754   ASSERT_NE(group, nullptr);
9755   auto device = group->GetFirstDevice();
9756 
9757   /* Simulate available context type being cleared */
9758   InjectAvailableContextTypes(device->address_, device->conn_id_, types::AudioContexts(0),
9759                               types::AudioContexts(0));
9760 
9761   /* Simulate ASE releasing and CIS Disconnection */
9762   for (auto& ase : device->ases_) {
9763     /* Releasing state */
9764     if (!ase.active) {
9765       continue;
9766     }
9767 
9768     std::vector<uint8_t> releasing_state = {
9769             ase.id, static_cast<uint8_t>(types::AseState::BTA_LE_AUDIO_ASE_STATE_RELEASING)};
9770     InjectNotificationEvent(device->address_, device->conn_id_, ase.hdls.val_hdl, releasing_state);
9771     SyncOnMainLoop();
9772     InjectCisDisconnected(group_id, ase.cis_conn_hdl);
9773     SyncOnMainLoop();
9774   }
9775 
9776   cis_count_out = 1;
9777   cis_count_in = 0;
9778   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
9779 
9780   /* Bring back available context types */
9781   InjectAvailableContextTypes(device->address_, device->conn_id_, types::kLeAudioContextAllTypes,
9782                               types::kLeAudioContextAllTypes);
9783 
9784   /* Check both devices are streaming */
9785   cis_count_out = 2;
9786   cis_count_in = 0;
9787   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
9788 }
9789 
TEST_F(UnicastTest,StartStream_AvailableContextTypeNotifiedLater)9790 TEST_F(UnicastTest, StartStream_AvailableContextTypeNotifiedLater) {
9791   uint8_t group_size = 2;
9792   int group_id = 2;
9793 
9794   available_snk_context_types_ = 0;
9795 
9796   /* Scenario (Devices A and B called "Remote")
9797    * 1. Remote  does supports all the context types, but has NO available
9798    * contexts at the beginning
9799    * 2. After connection Remote add Available context types
9800    * 3. Android start stream with MEDIA
9801    * 4. Make sure stream will be started
9802    */
9803 
9804   // Report working CSIS
9805   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
9806 
9807   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
9808           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
9809 
9810   const RawAddress test_address0 = GetTestAddress(0);
9811   const RawAddress test_address1 = GetTestAddress(1);
9812 
9813   // First earbud connects
9814   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
9815                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
9816 
9817   // Second earbud connects
9818   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
9819                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
9820                     true /*connect_through_csis*/);
9821 
9822   // Inject Supported and available context types
9823   auto sink_available_contexts = types::kLeAudioContextAllRemoteSinkOnly;
9824   auto source_available_contexts = types::kLeAudioContextAllRemoteSource;
9825 
9826   InjectAvailableContextTypes(test_address0, 1, sink_available_contexts, source_available_contexts);
9827   InjectAvailableContextTypes(test_address1, 2, sink_available_contexts, source_available_contexts);
9828   // Start streaming
9829   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
9830   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
9831   LeAudioClient::Get()->GroupSetActive(group_id);
9832   SyncOnMainLoop();
9833 
9834   BidirectionalPair<AudioContexts> contexts = {
9835           .sink = types::AudioContexts(types::LeAudioContextType::MEDIA),
9836           .source = types::AudioContexts()};
9837 
9838   EXPECT_CALL(mock_state_machine_,
9839               StartStream(_, bluetooth::le_audio::types::LeAudioContextType::MEDIA, contexts, _))
9840           .Times(1);
9841 
9842   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
9843   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
9844   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
9845 
9846   // Expect two iso channel to be fed with data
9847   uint8_t cis_count_out = 2;
9848   uint8_t cis_count_in = 0;
9849   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
9850 }
9851 
TEST_F(UnicastTest,ModifyContextTypeOnDeviceA_WhileDeviceB_IsDisconnected)9852 TEST_F(UnicastTest, ModifyContextTypeOnDeviceA_WhileDeviceB_IsDisconnected) {
9853   uint8_t group_size = 2;
9854   int group_id = 2;
9855 
9856   /* Scenario (Device A and B called Remote)
9857    * 1. Remote set does supports all the context types and make them available
9858    * 2. Android start stream with MEDIA, verify it works.
9859    * 3. Android stops the stream
9860    * 4. Device B disconnects
9861    * 5. Device A removes Media from Available Contexts
9862    * 6. Android start stream with MEDIA, verify it will not be started
9863    */
9864 
9865   // Report working CSIS
9866   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
9867 
9868   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
9869           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
9870 
9871   const RawAddress test_address0 = GetTestAddress(0);
9872   const RawAddress test_address1 = GetTestAddress(1);
9873 
9874   // First earbud connects
9875   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
9876                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
9877 
9878   // Second earbud connects
9879   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
9880                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
9881                     true /*connect_through_csis*/);
9882 
9883   // Start streaming
9884   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
9885   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
9886   LeAudioClient::Get()->GroupSetActive(group_id);
9887   SyncOnMainLoop();
9888 
9889   BidirectionalPair<AudioContexts> contexts = {
9890           .sink = types::AudioContexts(types::LeAudioContextType::MEDIA),
9891           .source = types::AudioContexts()};
9892 
9893   EXPECT_CALL(mock_state_machine_,
9894               StartStream(_, bluetooth::le_audio::types::LeAudioContextType::MEDIA, contexts, _))
9895           .Times(1);
9896 
9897   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
9898 
9899   SyncOnMainLoop();
9900   Mock::VerifyAndClearExpectations(&mock_state_machine_);
9901   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
9902   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
9903 
9904   // Expect two iso channel to be fed with data
9905   uint8_t cis_count_out = 2;
9906   uint8_t cis_count_in = 0;
9907   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
9908 
9909   // Stop
9910   StopStreaming(group_id);
9911   // simulate suspend timeout passed, alarm executing
9912   fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
9913   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
9914 
9915   // Device B got disconnected and will not reconnect.
9916   ON_CALL(mock_gatt_interface_, Open(_, test_address1, BTM_BLE_DIRECT_CONNECTION, _))
9917           .WillByDefault(Return());
9918   InjectDisconnectedEvent(2, GATT_CONN_TERMINATE_PEER_USER);
9919   SyncOnMainLoop();
9920 
9921   // Device A changes available context type
9922   // Inject Supported and available context types
9923   auto sink_supported_context = types::kLeAudioContextAllRemoteSinkOnly;
9924   sink_supported_context.unset(LeAudioContextType::MEDIA);
9925   sink_supported_context.set(LeAudioContextType::UNSPECIFIED);
9926 
9927   auto source_supported_context = types::kLeAudioContextAllRemoteSource;
9928   source_supported_context.set(LeAudioContextType::UNSPECIFIED);
9929 
9930   InjectSupportedContextTypes(test_address0, 1, sink_supported_context, source_supported_context);
9931   InjectAvailableContextTypes(test_address0, 1, sink_supported_context, source_supported_context);
9932 
9933   /* Android starts stream. */
9934   EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, _)).Times(0);
9935 
9936   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id, AUDIO_SOURCE_INVALID, false,
9937                  false);
9938   SyncOnMainLoop();
9939 
9940   Mock::VerifyAndClearExpectations(&mock_state_machine_);
9941 }
9942 
TEST_F(UnicastTest,StartStreamToUnsupportedContextTypeUsingUnspecified)9943 TEST_F(UnicastTest, StartStreamToUnsupportedContextTypeUsingUnspecified) {
9944   uint8_t group_size = 2;
9945   int group_id = 2;
9946 
9947   /* Scenario (Devices A and B called "Remote")
9948    * 1. Remote  does supports all the context types and make them available
9949    * 2. Remote removes SoundEffect from the supported and available context
9950    * types
9951    * 3. Android start stream with SoundEffects
9952    * 4. Make sure stream will be started with Unspecified context type
9953    */
9954 
9955   // Report working CSIS
9956   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
9957 
9958   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
9959           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
9960 
9961   const RawAddress test_address0 = GetTestAddress(0);
9962   const RawAddress test_address1 = GetTestAddress(1);
9963 
9964   // First earbud connects
9965   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
9966                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
9967 
9968   // Second earbud connects
9969   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
9970                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
9971                     true /*connect_through_csis*/);
9972 
9973   // Inject Supported and available context types
9974   auto sink_supported_context = types::kLeAudioContextAllRemoteSinkOnly;
9975   sink_supported_context.unset(LeAudioContextType::SOUNDEFFECTS);
9976   sink_supported_context.set(LeAudioContextType::UNSPECIFIED);
9977 
9978   auto source_supported_context = types::kLeAudioContextAllRemoteSource;
9979   source_supported_context.set(LeAudioContextType::UNSPECIFIED);
9980 
9981   InjectSupportedContextTypes(test_address0, 1, sink_supported_context, source_supported_context);
9982   InjectAvailableContextTypes(test_address0, 1, sink_supported_context, source_supported_context);
9983   InjectSupportedContextTypes(test_address1, 2, sink_supported_context, source_supported_context);
9984   InjectAvailableContextTypes(test_address1, 2, sink_supported_context, source_supported_context);
9985   // Start streaming
9986   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
9987   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
9988   LeAudioClient::Get()->GroupSetActive(group_id);
9989   SyncOnMainLoop();
9990 
9991   BidirectionalPair<AudioContexts> contexts = {
9992           .sink = types::AudioContexts(types::LeAudioContextType::UNSPECIFIED),
9993           .source = types::AudioContexts(0)};
9994 
9995   EXPECT_CALL(
9996           mock_state_machine_,
9997           StartStream(_, bluetooth::le_audio::types::LeAudioContextType::SOUNDEFFECTS, contexts, _))
9998           .Times(1);
9999 
10000   StartStreaming(AUDIO_USAGE_ASSISTANCE_SONIFICATION, AUDIO_CONTENT_TYPE_SONIFICATION, group_id);
10001 
10002   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
10003   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
10004   SyncOnMainLoop();
10005 
10006   // Expect two iso channel to be fed with data
10007   uint8_t cis_count_out = 2;
10008   uint8_t cis_count_in = 0;
10009   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
10010 }
10011 
TEST_F(UnicastTest,StartStreamToUnsupportedContextTypeUnspecifiedNotAvailable)10012 TEST_F(UnicastTest, StartStreamToUnsupportedContextTypeUnspecifiedNotAvailable) {
10013   uint8_t group_size = 2;
10014   int group_id = 2;
10015 
10016   /* Scenario (Device A and B called Remote)
10017    * 1. Remote does supports all the context types and make them available
10018    * 2. Remote removes SoundEffect from the Available Context Types
10019    * 3. Remote also removes UNSPECIFIED from the Available Context Types.
10020    * 4. Android start stream with SoundEffects
10021    * 5. Make sure stream will be NOT be started
10022    */
10023 
10024   // Report working CSIS
10025   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
10026 
10027   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
10028           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
10029 
10030   const RawAddress test_address0 = GetTestAddress(0);
10031   const RawAddress test_address1 = GetTestAddress(1);
10032 
10033   // First earbud connects
10034   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
10035                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
10036 
10037   // Second earbud connects
10038   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
10039                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
10040                     true /*connect_through_csis*/);
10041 
10042   // Inject Supported and available context types
10043   auto sink_supported_context = types::kLeAudioContextAllRemoteSinkOnly;
10044   sink_supported_context.unset(LeAudioContextType::SOUNDEFFECTS);
10045   sink_supported_context.set(LeAudioContextType::UNSPECIFIED);
10046 
10047   auto source_supported_context = types::kLeAudioContextAllRemoteSource;
10048   source_supported_context.set(LeAudioContextType::UNSPECIFIED);
10049 
10050   InjectSupportedContextTypes(test_address0, 1, sink_supported_context, source_supported_context);
10051   InjectSupportedContextTypes(test_address1, 2, sink_supported_context, source_supported_context);
10052 
10053   auto sink_available_context = sink_supported_context;
10054   sink_available_context.unset(LeAudioContextType::UNSPECIFIED);
10055 
10056   auto source_available_context = source_supported_context;
10057   source_available_context.unset(LeAudioContextType::UNSPECIFIED);
10058 
10059   InjectAvailableContextTypes(test_address0, 1, sink_available_context, source_available_context);
10060   InjectAvailableContextTypes(test_address1, 2, sink_available_context, source_available_context);
10061   // Start streaming
10062   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
10063   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
10064   LeAudioClient::Get()->GroupSetActive(group_id);
10065   SyncOnMainLoop();
10066 
10067   BidirectionalPair<AudioContexts> contexts = {
10068           .sink = types::AudioContexts(types::LeAudioContextType::UNSPECIFIED),
10069           .source = types::AudioContexts()};
10070 
10071   EXPECT_CALL(
10072           mock_state_machine_,
10073           StartStream(_, bluetooth::le_audio::types::LeAudioContextType::SOUNDEFFECTS, contexts, _))
10074           .Times(0);
10075 
10076   StartStreaming(AUDIO_USAGE_ASSISTANCE_SONIFICATION, AUDIO_CONTENT_TYPE_SONIFICATION, group_id,
10077                  AUDIO_SOURCE_INVALID, false, false);
10078 
10079   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
10080   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
10081   SyncOnMainLoop();
10082 }
10083 
TEST_F(UnicastTest,StartStreamToSupportedContextTypeThenMixUnavailable)10084 TEST_F(UnicastTest, StartStreamToSupportedContextTypeThenMixUnavailable) {
10085   uint8_t group_size = 2;
10086   int group_id = 2;
10087 
10088   /* Scenario (Device A and B called Remote)
10089    * 1. Remote set does supports all the context types and make them available
10090    * 2. Abdriud start stream with MEDIA, verify it works.
10091    * 3. Stream becomes to be mixed with Soundeffect and Media - verify metadata
10092    *    update
10093    * 4. Android Stop stream.
10094    * 5. Remote removes SoundEffect from the supported and available context
10095    * types
10096    * 6. Android start stream with MEDIA, verify it works.
10097    * 7. Stream becomes to be mixed with Soundeffect and Media
10098    * 8. Make sure metadata updated does not contain unavailable context
10099    *    note: eventually, Audio framework should not give us unwanted context
10100    * types
10101    */
10102 
10103   // Report working CSIS
10104   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
10105 
10106   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
10107           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
10108 
10109   const RawAddress test_address0 = GetTestAddress(0);
10110   const RawAddress test_address1 = GetTestAddress(1);
10111 
10112   // First earbud connects
10113   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
10114                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
10115 
10116   // Second earbud connects
10117   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
10118                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
10119                     true /*connect_through_csis*/);
10120 
10121   // Start streaming
10122   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
10123   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
10124   LeAudioClient::Get()->GroupSetActive(group_id);
10125   SyncOnMainLoop();
10126 
10127   BidirectionalPair<AudioContexts> contexts = {
10128           .sink = types::AudioContexts(types::LeAudioContextType::MEDIA),
10129           .source = types::AudioContexts()};
10130 
10131   EXPECT_CALL(mock_state_machine_,
10132               StartStream(_, bluetooth::le_audio::types::LeAudioContextType::MEDIA, contexts, _))
10133           .Times(1);
10134 
10135   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
10136 
10137   SyncOnMainLoop();
10138   Mock::VerifyAndClearExpectations(&mock_state_machine_);
10139   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
10140   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
10141 
10142   ASSERT_NE(0lu, streaming_groups.count(group_id));
10143   auto group = streaming_groups.at(group_id);
10144 
10145   // Expect two iso channel to be fed with data
10146   uint8_t cis_count_out = 2;
10147   uint8_t cis_count_in = 0;
10148   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
10149 
10150   contexts.sink = types::AudioContexts(types::LeAudioContextType::MEDIA |
10151                                        types::LeAudioContextType::SOUNDEFFECTS);
10152   EXPECT_CALL(mock_state_machine_,
10153               StartStream(_, bluetooth::le_audio::types::LeAudioContextType::MEDIA, contexts, _))
10154           .Times(1);
10155 
10156   /* Simulate metadata update, expect upadate , metadata */
10157   std::vector<struct playback_track_metadata> tracks = {
10158           {{AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, 0},
10159            {AUDIO_USAGE_ASSISTANCE_SONIFICATION, AUDIO_CONTENT_TYPE_SONIFICATION, 0}}};
10160   UpdateLocalSourceMetadata(tracks);
10161   SyncOnMainLoop();
10162 
10163   Mock::VerifyAndClearExpectations(&mock_state_machine_);
10164 
10165   /* Stop stream */
10166   StopStreaming(group_id);
10167   // simulate suspend timeout passed, alarm executing
10168   fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
10169   SyncOnMainLoop();
10170 
10171   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
10172 
10173   // Inject Supported and available context types
10174   auto sink_supported_context = types::kLeAudioContextAllRemoteSinkOnly;
10175   sink_supported_context.unset(LeAudioContextType::SOUNDEFFECTS);
10176   sink_supported_context.set(LeAudioContextType::UNSPECIFIED);
10177 
10178   auto source_supported_context = types::kLeAudioContextAllRemoteSource;
10179   source_supported_context.set(LeAudioContextType::UNSPECIFIED);
10180 
10181   InjectSupportedContextTypes(test_address0, 1, sink_supported_context, source_supported_context);
10182   InjectAvailableContextTypes(test_address0, 1, sink_supported_context, source_supported_context);
10183   InjectSupportedContextTypes(test_address1, 2, sink_supported_context, source_supported_context);
10184   InjectAvailableContextTypes(test_address1, 2, sink_supported_context, source_supported_context);
10185 
10186   // Verify cache has been removed due to available context change
10187   ASSERT_EQ(nullptr, group->GetCachedConfiguration(types::LeAudioContextType::MEDIA));
10188   /* Start Media again */
10189   contexts.sink = types::AudioContexts(types::LeAudioContextType::MEDIA);
10190   EXPECT_CALL(mock_state_machine_,
10191               StartStream(_, bluetooth::le_audio::types::LeAudioContextType::MEDIA, contexts, _))
10192           .Times(1);
10193 
10194   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
10195 
10196   SyncOnMainLoop();
10197 
10198   // Verify cache has been rebuilt
10199   ASSERT_NE(nullptr, group->GetCachedConfiguration(types::LeAudioContextType::MEDIA));
10200   ASSERT_TRUE(group->GetCachedConfiguration(types::LeAudioContextType::MEDIA)
10201                       ->confs.get(le_audio::types::kLeAudioDirectionSink)
10202                       .size());
10203 
10204   Mock::VerifyAndClearExpectations(&mock_state_machine_);
10205   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
10206   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
10207 
10208   // Expect two iso channel to be fed with data
10209   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
10210 
10211   /* Update metadata, and do not expect new context type*/
10212   EXPECT_CALL(mock_state_machine_,
10213               StartStream(_, bluetooth::le_audio::types::LeAudioContextType::MEDIA, contexts, _))
10214           .Times(1);
10215 
10216   /* Simulate metadata update */
10217   UpdateLocalSourceMetadata(tracks);
10218   SyncOnMainLoop();
10219   Mock::VerifyAndClearExpectations(&mock_state_machine_);
10220 }
10221 
TEST_F(UnicastTest,TwoEarbuds2ndDisconnected)10222 TEST_F(UnicastTest, TwoEarbuds2ndDisconnected) {
10223   uint8_t group_size = 2;
10224   int group_id = 2;
10225 
10226   // Report working CSIS
10227   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
10228 
10229   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
10230           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
10231 
10232   // First earbud
10233   const RawAddress test_address0 = GetTestAddress(0);
10234   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
10235                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
10236 
10237   // Second earbud
10238   const RawAddress test_address1 = GetTestAddress(1);
10239   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
10240                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
10241                     true /*connect_through_csis*/);
10242 
10243   // Audio sessions are started only when device gets active
10244   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
10245   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
10246   LeAudioClient::Get()->GroupSetActive(group_id);
10247   SyncOnMainLoop();
10248 
10249   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
10250   ASSERT_NE(0lu, streaming_groups.count(group_id));
10251   auto group = streaming_groups.at(group_id);
10252 
10253   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
10254   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
10255   SyncOnMainLoop();
10256   ASSERT_EQ(2, group->NumOfConnected());
10257 
10258   // Expect two iso channels to be fed with data
10259   uint8_t cis_count_out = 2;
10260   uint8_t cis_count_in = 0;
10261   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
10262 
10263   // Disconnect one device and expect the group to keep on streaming
10264   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(0);
10265   auto device = group->GetFirstDevice();
10266   for (auto& ase : device->ases_) {
10267     InjectCisDisconnected(group_id, ase.cis_conn_hdl);
10268   }
10269 
10270   /* Disconnect ACL and do not reconnect. */
10271   ON_CALL(mock_gatt_interface_, Open(_, device->address_, BTM_BLE_DIRECT_CONNECTION, _))
10272           .WillByDefault(Return());
10273   EXPECT_CALL(mock_gatt_interface_, Open(_, device->address_, BTM_BLE_DIRECT_CONNECTION, false))
10274           .Times(1);
10275 
10276   // Record NumOfConnected when groupStateMachine_ gets notified about the
10277   // disconnection
10278   int num_of_connected = 0;
10279   ON_CALL(mock_state_machine_, ProcessHciNotifAclDisconnected(_, _))
10280           .WillByDefault(
10281                   [&num_of_connected](LeAudioDeviceGroup* group, LeAudioDevice* /*leAudioDevice*/) {
10282                     num_of_connected = group->NumOfConnected();
10283                   });
10284 
10285   auto conn_id = device->conn_id_;
10286   InjectDisconnectedEvent(device->conn_id_, GATT_CONN_TERMINATE_PEER_USER);
10287   SyncOnMainLoop();
10288 
10289   // Make sure the state machine knows about the disconnected device
10290   ASSERT_EQ(1, num_of_connected);
10291 
10292   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
10293   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
10294 
10295   // Expect one channel ISO Data to be sent
10296   cis_count_out = 1;
10297   cis_count_in = 0;
10298   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
10299 
10300   InjectConnectedEvent(device->address_, conn_id);
10301   SyncOnMainLoop();
10302 
10303   // Expect two iso channels to be fed with data
10304   cis_count_out = 2;
10305   cis_count_in = 0;
10306   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
10307 }
10308 
TEST_F(UnicastTest,TwoEarbudsStreamingProfileDisconnect)10309 TEST_F(UnicastTest, TwoEarbudsStreamingProfileDisconnect) {
10310   uint8_t group_size = 2;
10311   int group_id = 2;
10312 
10313   // Report working CSIS
10314   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
10315 
10316   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
10317           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
10318 
10319   // First earbud
10320   const RawAddress test_address0 = GetTestAddress(0);
10321   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
10322                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
10323 
10324   // Second earbud
10325   const RawAddress test_address1 = GetTestAddress(1);
10326   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
10327                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
10328                     true /*connect_through_csis*/);
10329 
10330   // Audio sessions are started only when device gets active
10331   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
10332   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
10333   LeAudioClient::Get()->GroupSetActive(group_id);
10334   SyncOnMainLoop();
10335 
10336   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
10337 
10338   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
10339   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
10340   SyncOnMainLoop();
10341 
10342   // Expect two iso channels to be fed with data
10343   uint8_t cis_count_out = 2;
10344   uint8_t cis_count_in = 0;
10345   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
10346 
10347   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(1);
10348 
10349   /* Do not inject OPEN_EVENT by default */
10350   ON_CALL(mock_gatt_interface_, Open(_, _, _, _)).WillByDefault(DoAll(Return()));
10351   ON_CALL(mock_gatt_interface_, Close(_)).WillByDefault(DoAll(Return()));
10352   ON_CALL(mock_btm_interface_, AclDisconnectFromHandle(_, _)).WillByDefault(DoAll(Return()));
10353 
10354   DisconnectLeAudioNoDisconnectedEvtExpected(test_address0, 1);
10355   DisconnectLeAudioNoDisconnectedEvtExpected(test_address1, 2);
10356 
10357   EXPECT_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _))
10358           .Times(2);
10359 
10360   InjectDisconnectedEvent(1);
10361   InjectDisconnectedEvent(2);
10362 
10363   SyncOnMainLoop();
10364   Mock::VerifyAndClearExpectations(&mock_state_machine_);
10365   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
10366 }
10367 
TEST_F(UnicastTest,TwoEarbudsStreamingProfileDisconnectStreamStopTimeout)10368 TEST_F(UnicastTest, TwoEarbudsStreamingProfileDisconnectStreamStopTimeout) {
10369   uint8_t group_size = 2;
10370   int group_id = 2;
10371 
10372   // Report working CSIS
10373   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
10374 
10375   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
10376           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
10377 
10378   // First earbud
10379   const RawAddress test_address0 = GetTestAddress(0);
10380   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
10381                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
10382 
10383   // Second earbud
10384   const RawAddress test_address1 = GetTestAddress(1);
10385   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
10386                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
10387                     true /*connect_through_csis*/);
10388 
10389   // Audio sessions are started only when device gets active
10390   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
10391   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
10392   LeAudioClient::Get()->GroupSetActive(group_id);
10393   SyncOnMainLoop();
10394 
10395   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
10396 
10397   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
10398   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
10399   SyncOnMainLoop();
10400 
10401   // Expect two iso channels to be fed with data
10402   uint8_t cis_count_out = 2;
10403   uint8_t cis_count_in = 0;
10404   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
10405 
10406   // Expect StopStream to be called before Close or ACL Disconnect is called.
10407   ON_CALL(mock_state_machine_, StopStream(_)).WillByDefault([](LeAudioDeviceGroup* group) {
10408     /* Stub the process of stopping stream, just set the target state.
10409      * this simulates issue with stopping the stream
10410      */
10411     group->SetTargetState(types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE);
10412   });
10413 
10414   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(2);
10415   EXPECT_CALL(mock_gatt_interface_, Close(_)).Times(0);
10416   EXPECT_CALL(mock_btm_interface_, AclDisconnectFromHandle(_, _)).Times(0);
10417 
10418   do_in_main_thread(base::Bind(&LeAudioClient::Disconnect, base::Unretained(LeAudioClient::Get()),
10419                                test_address0));
10420   do_in_main_thread(base::Bind(&LeAudioClient::Disconnect, base::Unretained(LeAudioClient::Get()),
10421                                test_address1));
10422 
10423   SyncOnMainLoop();
10424   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
10425   Mock::VerifyAndClearExpectations(&mock_btm_interface_);
10426   Mock::VerifyAndClearExpectations(&mock_state_machine_);
10427 
10428   /* Now stream is trying to be stopped and devices are about to be
10429    * disconnected. Simulate stop stream failure and timeout fired. Make sure
10430    * code will not try to do recovery connect
10431    */
10432   ON_CALL(mock_btm_interface_, AclDisconnectFromHandle(_, _)).WillByDefault(DoAll(Return()));
10433   EXPECT_CALL(mock_gatt_interface_, Close(_)).Times(0);
10434   EXPECT_CALL(mock_btm_interface_, AclDisconnectFromHandle(_, _)).Times(2);
10435 
10436   ASSERT_NE(0lu, streaming_groups.count(group_id));
10437   auto group = streaming_groups.at(group_id);
10438   ASSERT_TRUE(group != nullptr);
10439   ASSERT_GT(group->NumOfConnected(), 0);
10440 
10441   state_machine_callbacks_->OnStateTransitionTimeout(group_id);
10442   SyncOnMainLoop();
10443 
10444   Mock::VerifyAndClearExpectations(&mock_btm_interface_);
10445   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
10446 
10447   auto device = group->GetFirstDevice();
10448   ASSERT_TRUE(device != nullptr);
10449   ASSERT_NE(device->GetConnectionState(), DeviceConnectState::DISCONNECTING_AND_RECOVER);
10450   device = group->GetNextDevice(device);
10451   ASSERT_TRUE(device != nullptr);
10452   ASSERT_NE(device->GetConnectionState(), DeviceConnectState::DISCONNECTING_AND_RECOVER);
10453 }
10454 
TEST_F(UnicastTest,TwoEarbudsStreamingProfileDisconnectForSingleEarbudStreamStopTimeout)10455 TEST_F(UnicastTest, TwoEarbudsStreamingProfileDisconnectForSingleEarbudStreamStopTimeout) {
10456   uint8_t group_size = 2;
10457   int group_id = 2;
10458 
10459   // Report working CSIS
10460   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
10461 
10462   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
10463           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
10464 
10465   // First earbud
10466   const RawAddress test_address0 = GetTestAddress(0);
10467   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
10468                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
10469 
10470   // Second earbud
10471   const RawAddress test_address1 = GetTestAddress(1);
10472   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
10473                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
10474                     true /*connect_through_csis*/);
10475 
10476   // Audio sessions are started only when device gets active
10477   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
10478   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
10479   LeAudioClient::Get()->GroupSetActive(group_id);
10480   SyncOnMainLoop();
10481 
10482   /* Use StartStream to generate situation when target state is IDLE, one device is streaming and
10483    * other one reached IDLE state.
10484    */
10485   ON_CALL(mock_state_machine_, StartStream(_, _, _, _))
10486           .WillByDefault([this](LeAudioDeviceGroup* group,
10487                                 types::LeAudioContextType /* context_type */,
10488                                 types::BidirectionalPair<
10489                                         types::AudioContexts> /* metadata_context_types */,
10490                                 types::BidirectionalPair<std::vector<uint8_t>> /* ccid_lists */) {
10491             group->SetTargetState(types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE);
10492             auto group_state = group->GetState();
10493             LeAudioDevice* device = group->GetFirstDevice();
10494             for (auto& ase : device->ases_) {
10495               ase.state = types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING;
10496               ase.active = true;
10497             }
10498             device = group->GetNextDevice(device);
10499             for (auto& ase : device->ases_) {
10500               ase.state = types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE;
10501               ase.active = false;
10502             }
10503 
10504             state_machine_callbacks_->OnStateTransitionTimeout(group->group_id_);
10505 
10506             return true;
10507           });
10508 
10509   // Do not accept direct connect, but expect it to arrive.
10510   ON_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_DIRECT_CONNECTION, _)).WillByDefault(Return());
10511 
10512   EXPECT_CALL(mock_btm_interface_, AclDisconnectFromHandle(_, _)).Times(1);
10513   EXPECT_CALL(mock_audio_hal_client_callbacks_, OnGroupStatus(group_id, GroupStatus::INACTIVE))
10514           .Times(0);
10515   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id, AUDIO_SOURCE_INVALID, false,
10516                  false);
10517   SyncOnMainLoop();
10518 }
10519 
TEST_F(UnicastTest,EarbudsWithStereoSinkMonoSourceSupporting32kHz)10520 TEST_F(UnicastTest, EarbudsWithStereoSinkMonoSourceSupporting32kHz) {
10521   const RawAddress test_address0 = GetTestAddress(0);
10522   int group_id = 0;
10523   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
10524                                 codec_spec_conf::kLeAudioLocationFrontLeft, default_channel_cnt,
10525                                 default_channel_cnt, 0x0024,
10526                                 /* source sample freq 32/16khz */ true, /*add_csis*/
10527                                 true,                                   /*add_cas*/
10528                                 true,                                   /*add_pacs*/
10529                                 default_ase_cnt /*add_ascs_cnt*/);
10530   EXPECT_CALL(mock_audio_hal_client_callbacks_,
10531               OnConnectionState(ConnectionState::CONNECTED, test_address0))
10532           .Times(1);
10533   ConnectLeAudio(test_address0);
10534 
10535   // LeAudioCodecConfiguration received_af_sink_config;
10536   const LeAudioCodecConfiguration expected_af_sink_config = {
10537           .num_channels = 2,
10538           .sample_rate = bluetooth::audio::le_audio::kSampleRate32000,
10539           .bits_per_sample = bluetooth::audio::le_audio::kBitsPerSample16,
10540           .data_interval_us = LeAudioCodecConfiguration::kInterval10000Us,
10541   };
10542 
10543   // Audio sessions are started only when device gets active
10544   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
10545   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(expected_af_sink_config, _, _)).Times(1);
10546   LeAudioClient::Get()->GroupSetActive(group_id);
10547   SyncOnMainLoop();
10548 }
10549 
TEST_F(UnicastTest,TwoEarbudsWithSourceSupporting32kHz)10550 TEST_F(UnicastTest, TwoEarbudsWithSourceSupporting32kHz) {
10551   const RawAddress test_address0 = GetTestAddress(0);
10552   int group_id = 0;
10553   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
10554                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
10555                                 default_channel_cnt, 0x0024,
10556                                 /* source sample freq 32/16khz */ true, /*add_csis*/
10557                                 true,                                   /*add_cas*/
10558                                 true,                                   /*add_pacs*/
10559                                 default_ase_cnt /*add_ascs_cnt*/);
10560   EXPECT_CALL(mock_audio_hal_client_callbacks_,
10561               OnConnectionState(ConnectionState::CONNECTED, test_address0))
10562           .Times(1);
10563   ConnectLeAudio(test_address0);
10564 
10565   // LeAudioCodecConfiguration received_af_sink_config;
10566   const LeAudioCodecConfiguration expected_af_sink_config = {
10567           .num_channels = 2,
10568           .sample_rate = bluetooth::audio::le_audio::kSampleRate32000,
10569           .bits_per_sample = bluetooth::audio::le_audio::kBitsPerSample16,
10570           .data_interval_us = LeAudioCodecConfiguration::kInterval10000Us,
10571   };
10572 
10573   // Audio sessions are started only when device gets active
10574   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
10575   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(expected_af_sink_config, _, _)).Times(1);
10576   LeAudioClient::Get()->GroupSetActive(group_id);
10577   SyncOnMainLoop();
10578 }
10579 
TEST_F(UnicastTest,MicrophoneAttachToCurrentMediaScenario)10580 TEST_F(UnicastTest, MicrophoneAttachToCurrentMediaScenario) {
10581   const RawAddress test_address0 = GetTestAddress(0);
10582   int group_id = bluetooth::groups::kGroupUnknown;
10583 
10584   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
10585                                 codec_spec_conf::kLeAudioLocationFrontLeft, default_channel_cnt,
10586                                 default_channel_cnt, 0x0024, false /*add_csis*/, true /*add_cas*/,
10587                                 true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
10588                                 0 /*rank*/);
10589   EXPECT_CALL(mock_audio_hal_client_callbacks_,
10590               OnConnectionState(ConnectionState::CONNECTED, test_address0))
10591           .Times(1);
10592   EXPECT_CALL(mock_audio_hal_client_callbacks_,
10593               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
10594           .WillOnce(DoAll(SaveArg<1>(&group_id)));
10595 
10596   ConnectLeAudio(test_address0);
10597   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
10598 
10599   // Audio sessions are started only when device gets active
10600   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
10601   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
10602   LeAudioClient::Get()->GroupSetActive(group_id);
10603   SyncOnMainLoop();
10604 
10605   // When the local audio source resumes we have no knowledge of recording
10606   EXPECT_CALL(mock_state_machine_,
10607               StartStream(_, bluetooth::le_audio::types::LeAudioContextType::MEDIA, _, _))
10608           .Times(1);
10609 
10610   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id, AUDIO_SOURCE_INVALID);
10611   SyncOnMainLoop();
10612 
10613   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
10614   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
10615 
10616   // Verify Data transfer on one audio source cis
10617   uint8_t cis_count_out = 1;
10618   uint8_t cis_count_in = 0;
10619   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
10620 
10621   // When the local audio sink resumes we should reconfigure
10622   EXPECT_CALL(mock_state_machine_,
10623               ConfigureStream(_, bluetooth::le_audio::types::LeAudioContextType::LIVE, _, _, _))
10624           .Times(1);
10625   EXPECT_CALL(*mock_le_audio_source_hal_client_, ReconfigurationComplete()).Times(1);
10626 
10627   // Update metadata on local audio sink
10628   UpdateLocalSinkMetadata(AUDIO_SOURCE_MIC);
10629 
10630   // Resume on local audio sink
10631   ASSERT_NE(unicast_sink_hal_cb_, nullptr);
10632   do_in_main_thread(
10633           base::BindOnce([](LeAudioSinkAudioHalClient::Callbacks* cb) { cb->OnAudioResume(); },
10634                          unicast_sink_hal_cb_));
10635 
10636   /* The above will trigger reconfiguration. After that Audio Hal action
10637    * is needed to restart the stream */
10638   SyncOnMainLoop();
10639 
10640   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
10641   Mock::VerifyAndClearExpectations(&mock_state_machine_);
10642 
10643   LocalAudioSourceResume();
10644   do_in_main_thread(
10645           base::BindOnce([](LeAudioSinkAudioHalClient::Callbacks* cb) { cb->OnAudioResume(); },
10646                          unicast_sink_hal_cb_));
10647   SyncOnMainLoop();
10648 
10649   auto group = streaming_groups.at(group_id);
10650   group->PrintDebugState();
10651 
10652   // Verify Data transfer on one audio source and sink cis
10653   cis_count_out = 1;
10654   cis_count_in = 1;
10655   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 60);
10656 
10657   // Stop
10658   StopStreaming(group_id);
10659   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
10660 
10661   // Release
10662   EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop()).Times(1);
10663   EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(1);
10664   EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(1);
10665   do_in_main_thread(base::BindOnce(
10666           [](LeAudioClient* client) { client->GroupSetActive(bluetooth::groups::kGroupUnknown); },
10667           LeAudioClient::Get()));
10668   SyncOnMainLoop();
10669 
10670   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
10671 }
10672 
TEST_F(UnicastTest,SwitchBetweenMicrophoneAndSoundEffectScenario)10673 TEST_F(UnicastTest, SwitchBetweenMicrophoneAndSoundEffectScenario) {
10674   const RawAddress test_address0 = GetTestAddress(0);
10675   int group_id = bluetooth::groups::kGroupUnknown;
10676 
10677   /* Scenario:
10678    * 1. User starts Recording - this creates bidiretional CISes
10679    * 2. User stops recording  - this starts suspend timeout (500ms)
10680    * 3. Since user touch the screen it generates touch tone - this shall reuse existing CISes when
10681    * it happens 500ms before stop
10682    */
10683   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
10684                                 codec_spec_conf::kLeAudioLocationFrontLeft, default_channel_cnt,
10685                                 default_channel_cnt, 0x0024, false /*add_csis*/, true /*add_cas*/,
10686                                 true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
10687                                 0 /*rank*/);
10688   EXPECT_CALL(mock_audio_hal_client_callbacks_,
10689               OnConnectionState(ConnectionState::CONNECTED, test_address0))
10690           .Times(1);
10691   EXPECT_CALL(mock_audio_hal_client_callbacks_,
10692               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
10693           .WillOnce(DoAll(SaveArg<1>(&group_id)));
10694 
10695   ConnectLeAudio(test_address0);
10696   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
10697 
10698   // Audio sessions are started only when device gets active
10699   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
10700   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
10701   LeAudioClient::Get()->GroupSetActive(group_id);
10702   SyncOnMainLoop();
10703 
10704   // When the local audio source resumes we have no knowledge of recording
10705   EXPECT_CALL(mock_state_machine_,
10706               StartStream(_, bluetooth::le_audio::types::LeAudioContextType::LIVE, _, _))
10707           .Times(1);
10708 
10709   log::info("Start Microphone recording - bidirectional CISes are expected");
10710   UpdateLocalSinkMetadata(AUDIO_SOURCE_MIC);
10711   LocalAudioSinkResume();
10712 
10713   ASSERT_EQ(0, get_func_call_count("alarm_set_on_mloop"));
10714   SyncOnMainLoop();
10715 
10716   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
10717   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
10718   Mock::VerifyAndClearExpectations(&mock_state_machine_);
10719 
10720   // Verify Data transfer on one audio source cis
10721   uint8_t cis_count_out = 0;
10722   uint8_t cis_count_in = 1;
10723   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 60);
10724 
10725   log::info("Suspend microphone recording - suspend timeout is not fired");
10726   LocalAudioSinkSuspend();
10727   SyncOnMainLoop();
10728 
10729   log::info("Expect VBC and Suspend timeouts to be started");
10730   ASSERT_EQ(2, get_func_call_count("alarm_set_on_mloop"));
10731   ASSERT_EQ(0, get_func_call_count("alarm_cancel"));
10732 
10733   log::info("Resume local source with touch tone - expect suspend timeout to be canceled");
10734 
10735   UpdateLocalSourceMetadata(AUDIO_USAGE_ASSISTANCE_SONIFICATION, AUDIO_CONTENT_TYPE_SONIFICATION);
10736   LocalAudioSourceResume();
10737   SyncOnMainLoop();
10738 
10739   log::info("Expect VBC and Suspend timeouts to be started");
10740   ASSERT_EQ(2, get_func_call_count("alarm_set_on_mloop"));
10741 
10742   auto group = streaming_groups.at(group_id);
10743   group->PrintDebugState();
10744 
10745   // Verify Data transfer on one audio source and sink cis
10746   cis_count_out = 1;
10747   cis_count_in = 0;
10748   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 60);
10749 }
10750 
TEST_F(UnicastTest,SwitchBetweenSoundEffectAndMicrophoneScenario)10751 TEST_F(UnicastTest, SwitchBetweenSoundEffectAndMicrophoneScenario) {
10752   const RawAddress test_address0 = GetTestAddress(0);
10753   int group_id = bluetooth::groups::kGroupUnknown;
10754 
10755   /* Scenario:
10756    * 1. User starts Recording which first triggers SoundEffect
10757    * 2. Just after that LIVE metadata arrives and this creates bidiretional CISes
10758    */
10759   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
10760                                 codec_spec_conf::kLeAudioLocationFrontLeft, default_channel_cnt,
10761                                 default_channel_cnt, 0x0024, false /*add_csis*/, true /*add_cas*/,
10762                                 true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
10763                                 0 /*rank*/);
10764   EXPECT_CALL(mock_audio_hal_client_callbacks_,
10765               OnConnectionState(ConnectionState::CONNECTED, test_address0))
10766           .Times(1);
10767   EXPECT_CALL(mock_audio_hal_client_callbacks_,
10768               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
10769           .WillOnce(DoAll(SaveArg<1>(&group_id)));
10770 
10771   ConnectLeAudio(test_address0);
10772   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
10773 
10774   // Audio sessions are started only when device gets active
10775   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
10776   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
10777   LeAudioClient::Get()->GroupSetActive(group_id);
10778   SyncOnMainLoop();
10779 
10780   // When the local audio source resumes we have no knowledge of recording
10781   EXPECT_CALL(mock_state_machine_,
10782               StartStream(_, bluetooth::le_audio::types::LeAudioContextType::SOUNDEFFECTS, _, _))
10783           .Times(1);
10784 
10785   StartStreaming(AUDIO_USAGE_ASSISTANCE_SONIFICATION, AUDIO_CONTENT_TYPE_SONIFICATION, group_id);
10786   SyncOnMainLoop();
10787 
10788   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
10789   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
10790   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
10791   Mock::VerifyAndClearExpectations(&mock_state_machine_);
10792 
10793   auto group = streaming_groups.at(group_id);
10794   group->PrintDebugState();
10795 
10796   log::info("Start Microphone recording - reconfiguration is expected");
10797   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(1);
10798   EXPECT_CALL(*mock_le_audio_source_hal_client_, CancelStreamingRequest()).Times(1);
10799   EXPECT_CALL(*mock_le_audio_sink_hal_client_, CancelStreamingRequest()).Times(1);
10800 
10801   UpdateLocalSinkMetadata(AUDIO_SOURCE_MIC);
10802   LocalAudioSinkResume();
10803 
10804   SyncOnMainLoop();
10805   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
10806   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
10807   group->PrintDebugState();
10808 
10809   log::info("Resume after reconfiguration - bidirectional CISes are expected");
10810   LocalAudioSourceResume();
10811   LocalAudioSinkResume();
10812 
10813   // Verify Data transfer on one audio source cis
10814   uint8_t cis_count_out = 0;
10815   uint8_t cis_count_in = 1;
10816   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 60);
10817 
10818   ASSERT_EQ(1, get_func_call_count("alarm_set_on_mloop"));
10819   ASSERT_EQ(0, get_func_call_count("alarm_cancel"));
10820 }
10821 
10822 /* When a certain context is unavailable and not supported we should stream
10823  * as UNSPECIFIED for the backwards compatibility.
10824  * Since UNSPECIFIED is available, put the UNSPECIFIED into the metadata instead
10825  * What we can do now is to keep streaming (and reconfigure if needed for the
10826  * use case).
10827  */
TEST_F(UnicastTest,UpdateNotSupportedContextTypeUnspecifiedAvailable_SpeedUpReconfigFlagEnabled)10828 TEST_F(UnicastTest, UpdateNotSupportedContextTypeUnspecifiedAvailable_SpeedUpReconfigFlagEnabled) {
10829   const RawAddress test_address0 = GetTestAddress(0);
10830   int group_id = bluetooth::groups::kGroupUnknown;
10831 
10832   available_snk_context_types_ =
10833           (types::LeAudioContextType::RINGTONE | types::LeAudioContextType::CONVERSATIONAL |
10834            types::LeAudioContextType::UNSPECIFIED | types::LeAudioContextType::MEDIA)
10835                   .value();
10836   supported_snk_context_types_ = available_snk_context_types_;
10837   available_src_context_types_ = available_snk_context_types_;
10838   supported_src_context_types_ = available_src_context_types_;
10839 
10840   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
10841                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
10842                                 default_channel_cnt, 0x0004, false /*add_csis*/, true /*add_cas*/,
10843                                 true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
10844                                 0 /*rank*/);
10845   EXPECT_CALL(mock_audio_hal_client_callbacks_,
10846               OnConnectionState(ConnectionState::CONNECTED, test_address0))
10847           .Times(1);
10848   EXPECT_CALL(mock_audio_hal_client_callbacks_,
10849               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
10850           .WillOnce(DoAll(SaveArg<1>(&group_id)));
10851 
10852   ConnectLeAudio(test_address0);
10853   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
10854 
10855   // Start streaming
10856   uint8_t cis_count_out = 1;
10857   uint8_t cis_count_in = 0;
10858 
10859   LeAudioClient::Get()->SetInCall(true);
10860 
10861   // Audio sessions are started only when device gets active
10862   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
10863   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
10864   LeAudioClient::Get()->GroupSetActive(group_id);
10865   SyncOnMainLoop();
10866 
10867   StartStreaming(AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE, AUDIO_CONTENT_TYPE_UNKNOWN, group_id);
10868   LocalAudioSourceResume();
10869   LocalAudioSinkResume();
10870 
10871   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
10872   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
10873   SyncOnMainLoop();
10874 
10875   // Verify Data transfer on one audio source cis
10876   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
10877 
10878   LeAudioClient::Get()->SetInCall(false);
10879   LocalAudioSinkSuspend();
10880 
10881   /* We should use GAME configuration, but do not send the GAME context type, as
10882    * it is not available on the remote device.
10883    */
10884   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(0);
10885   types::BidirectionalPair<types::AudioContexts> contexts = {
10886           .sink = types::AudioContexts(types::LeAudioContextType::UNSPECIFIED),
10887           .source = types::AudioContexts()};
10888   EXPECT_CALL(mock_state_machine_, StartStream(_, types::LeAudioContextType::GAME, contexts, _))
10889           .Times(1);
10890   UpdateLocalSourceMetadata(AUDIO_USAGE_GAME, AUDIO_CONTENT_TYPE_UNKNOWN, false);
10891   SyncOnMainLoop();
10892 }
10893 
10894 /* Some bidirectional scenarios are triggered by the local sink, local source
10895  * metadata or the In Call preference callback call. Since each call invalidates
10896  * previous context source, make sure that getting all of these in a sequence,
10897  * always results with one bidirectional context, so that the remote device
10898  * is not confused about our intentions.
10899  */
TEST_F(UnicastTest,UpdateMultipleBidirContextTypes_SpeedUpReconfigFlagEnabled)10900 TEST_F(UnicastTest, UpdateMultipleBidirContextTypes_SpeedUpReconfigFlagEnabled) {
10901   const RawAddress test_address0 = GetTestAddress(0);
10902   int group_id = bluetooth::groups::kGroupUnknown;
10903 
10904   available_snk_context_types_ = (types::LeAudioContextType::CONVERSATIONAL |
10905                                   types::LeAudioContextType::GAME | types::LeAudioContextType::LIVE)
10906                                          .value();
10907   supported_snk_context_types_ =
10908           available_snk_context_types_ |
10909           types::AudioContexts(types::LeAudioContextType::UNSPECIFIED).value();
10910   available_src_context_types_ = available_snk_context_types_;
10911   supported_src_context_types_ =
10912           available_src_context_types_ |
10913           types::AudioContexts(types::LeAudioContextType::UNSPECIFIED).value();
10914 
10915   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationAnyLeft,
10916                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
10917                                 default_channel_cnt, 0x0024, false /*add_csis*/, true /*add_cas*/,
10918                                 true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
10919                                 0 /*rank*/);
10920   EXPECT_CALL(mock_audio_hal_client_callbacks_,
10921               OnConnectionState(ConnectionState::CONNECTED, test_address0))
10922           .Times(1);
10923   EXPECT_CALL(mock_audio_hal_client_callbacks_,
10924               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
10925           .WillOnce(DoAll(SaveArg<1>(&group_id)));
10926 
10927   ConnectLeAudio(test_address0);
10928   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
10929 
10930   // Audio sessions are started only when device gets active
10931   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
10932   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
10933   LeAudioClient::Get()->GroupSetActive(group_id);
10934   SyncOnMainLoop();
10935 
10936   // When the local audio sink resumes expect only LIVE context
10937   types::BidirectionalPair<types::AudioContexts> contexts = {
10938           .sink = types::AudioContexts(types::LeAudioContextType::LIVE),
10939           .source = types::AudioContexts(types::LeAudioContextType::LIVE)};
10940   EXPECT_CALL(mock_state_machine_,
10941               StartStream(_, bluetooth::le_audio::types::LeAudioContextType::LIVE, contexts, _))
10942           .Times(1);
10943 
10944   log::info("Step 1 Start the recording. Sink resume will trigger the reconfiguration");
10945   // ---------------------------------------------------------------------
10946   ASSERT_NE(nullptr, unicast_sink_hal_cb_);
10947   UpdateLocalSinkMetadata(AUDIO_SOURCE_MIC);
10948   LocalAudioSinkResume();
10949 
10950   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
10951   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
10952   Mock::VerifyAndClearExpectations(&mock_state_machine_);
10953 
10954   log::info("After the reconfiguration the local Audio Sink HAL has to resume again");
10955 
10956   LocalAudioSourceResume();
10957   LocalAudioSinkResume();
10958 
10959   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
10960   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
10961   Mock::VerifyAndClearExpectations(&mock_state_machine_);
10962 
10963   log::info("Verify Data transfer on one audio source and sink cis");
10964 
10965   uint8_t cis_count_out = 1;
10966   uint8_t cis_count_in = 1;
10967   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 40);
10968 
10969   log::info("Step 2 Now set in call preference to get CONVERSATIONAL into the mix");
10970   // -----------------------------------------------------------------
10971 
10972   EXPECT_CALL(*mock_le_audio_source_hal_client_, SuspendedForReconfiguration()).Times(0);
10973   EXPECT_CALL(*mock_le_audio_source_hal_client_, CancelStreamingRequest()).Times(0);
10974   EXPECT_CALL(*mock_le_audio_source_hal_client_, ReconfigurationComplete()).Times(0);
10975   EXPECT_CALL(mock_state_machine_, ConfigureStream(_, _, _, _, _)).Times(0);
10976   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(0);
10977   LeAudioClient::Get()->SetInCall(true);
10978   SyncOnMainLoop();
10979 
10980   // Verify that we only got CONVERSATIONAL context and no LIVE
10981   contexts = {.sink = types::AudioContexts(types::LeAudioContextType::CONVERSATIONAL),
10982               .source = types::AudioContexts(types::LeAudioContextType::CONVERSATIONAL)};
10983   EXPECT_CALL(mock_state_machine_,
10984               StartStream(_, bluetooth::le_audio::types::LeAudioContextType::CONVERSATIONAL,
10985                           contexts, _))
10986           .Times(1);
10987 
10988   log::info("Start with ringtone on local source");
10989   ASSERT_NE(nullptr, unicast_sink_hal_cb_);
10990   StartStreaming(AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE, AUDIO_CONTENT_TYPE_UNKNOWN, group_id);
10991 
10992   // Resume both directions
10993   LocalAudioSourceResume();
10994   LocalAudioSinkResume();
10995 
10996   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
10997   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
10998   Mock::VerifyAndClearExpectations(&mock_state_machine_);
10999 
11000   // Verify Data transfer on one audio source cis
11001   cis_count_out = 1;
11002   cis_count_in = 1;
11003   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 40);
11004 
11005   log::info("Step 3 Disable call so we could go to GAME");
11006   // ---------------------------------------
11007   EXPECT_CALL(*mock_le_audio_source_hal_client_, SuspendedForReconfiguration()).Times(0);
11008   EXPECT_CALL(*mock_le_audio_source_hal_client_, CancelStreamingRequest()).Times(0);
11009   EXPECT_CALL(*mock_le_audio_source_hal_client_, ReconfigurationComplete()).Times(0);
11010   EXPECT_CALL(mock_state_machine_, ConfigureStream(_, _, _, _, _)).Times(0);
11011   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(0);
11012 
11013   LeAudioClient::Get()->SetInCall(false);
11014   SyncOnMainLoop();
11015   Mock::VerifyAndClearExpectations(&mock_state_machine_);
11016   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
11017 
11018   log::info("Start the game on local source - expect no previous sink (LIVE) metadata");
11019 
11020   /* Stream shall keep streaming */
11021   contexts = {.sink = types::AudioContexts(types::LeAudioContextType::GAME),
11022               .source = types::AudioContexts(types::LeAudioContextType::GAME)};
11023   EXPECT_CALL(mock_state_machine_, StartStream(_, _, contexts, _)).Times(1);
11024 
11025   UpdateLocalSourceMetadata(AUDIO_USAGE_GAME, AUDIO_CONTENT_TYPE_UNKNOWN, false);
11026   LocalAudioSourceResume();
11027   SyncOnMainLoop();
11028 
11029   // Verify Data transfer on one audio source cis
11030   cis_count_out = 1;
11031   cis_count_in = 1;
11032   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 40);
11033   Mock::VerifyAndClearExpectations(&mock_state_machine_);
11034 
11035   log::info(" Step 4 Stop streaming");
11036   // ------------------
11037   StopStreaming(group_id);
11038   SyncOnMainLoop();
11039   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
11040 
11041   // Release
11042   EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop()).Times(1);
11043   EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(1);
11044   EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(1);
11045   do_in_main_thread(base::BindOnce(
11046           [](LeAudioClient* client) { client->GroupSetActive(bluetooth::groups::kGroupUnknown); },
11047           LeAudioClient::Get()));
11048   SyncOnMainLoop();
11049 }
11050 
TEST_F(UnicastTest,UpdateDisableLocalAudioSinkOnGame)11051 TEST_F(UnicastTest, UpdateDisableLocalAudioSinkOnGame) {
11052   const RawAddress test_address0 = GetTestAddress(0);
11053   int group_id = bluetooth::groups::kGroupUnknown;
11054 
11055   available_snk_context_types_ = (types::LeAudioContextType::CONVERSATIONAL |
11056                                   types::LeAudioContextType::GAME | types::LeAudioContextType::LIVE)
11057                                          .value();
11058   supported_snk_context_types_ =
11059           available_snk_context_types_ |
11060           types::AudioContexts(types::LeAudioContextType::UNSPECIFIED).value();
11061   available_src_context_types_ = available_snk_context_types_;
11062   supported_src_context_types_ =
11063           available_src_context_types_ |
11064           types::AudioContexts(types::LeAudioContextType::UNSPECIFIED).value();
11065 
11066   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationAnyLeft,
11067                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
11068                                 default_channel_cnt, 0x0024, false /*add_csis*/, true /*add_cas*/,
11069                                 true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
11070                                 0 /*rank*/);
11071   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11072               OnConnectionState(ConnectionState::CONNECTED, test_address0))
11073           .Times(1);
11074   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11075               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
11076           .WillOnce(DoAll(SaveArg<1>(&group_id)));
11077 
11078   ConnectLeAudio(test_address0);
11079   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
11080 
11081   // Audio sessions are started only when device gets active
11082   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
11083   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
11084   LeAudioClient::Get()->GroupSetActive(group_id);
11085   SyncOnMainLoop();
11086 
11087   // Start GAME stream
11088   types::BidirectionalPair<types::AudioContexts> contexts = {
11089           .sink = types::AudioContexts(types::LeAudioContextType::GAME),
11090           .source = types::AudioContexts(types::LeAudioContextType::GAME)};
11091   EXPECT_CALL(mock_state_machine_,
11092               StartStream(_, bluetooth::le_audio::types::LeAudioContextType::GAME, contexts, _))
11093           .Times(1);
11094 
11095   // 1) Start the recording. Sink resume will trigger the reconfiguration
11096   // ---------------------------------------------------------------------
11097   StartStreaming(AUDIO_USAGE_GAME, AUDIO_CONTENT_TYPE_MUSIC, group_id, AUDIO_SOURCE_MIC);
11098 
11099   SyncOnMainLoop();
11100 
11101   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
11102   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
11103   Mock::VerifyAndClearExpectations(&mock_state_machine_);
11104 
11105   // Verify Data transfer on one audio source and sink cis
11106   uint8_t cis_count_out = 1;
11107   uint8_t cis_count_in = 1;
11108   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 40);
11109 
11110   SyncOnMainLoop();
11111 
11112   // 2) Now Lets suspend MIC and do not expect reconfiguration
11113   // -----------------------------------------------------------------
11114 
11115   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(0);
11116   LocalAudioSinkSuspend();
11117   // simulate suspend timeout passed, alarm executing
11118   fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
11119   SyncOnMainLoop();
11120   Mock::VerifyAndClearExpectations(&mock_state_machine_);
11121 }
11122 
11123 /* Start music when in a call, end the call, continue with music only */
TEST_F(UnicastTest,MetadataUpdateDuringReconfiguration)11124 TEST_F(UnicastTest, MetadataUpdateDuringReconfiguration) {
11125   const RawAddress test_address0 = GetTestAddress(0);
11126   int group_id = bluetooth::groups::kGroupUnknown;
11127 
11128   /* Scenario
11129    * 1. Start reconfiguration
11130    * 2. Send metadata update
11131    * 3. Make sure metadata updates are ignored
11132    */
11133   available_snk_context_types_ =
11134           (types::LeAudioContextType::CONVERSATIONAL | types::LeAudioContextType::RINGTONE |
11135            types::LeAudioContextType::GAME | types::LeAudioContextType::MEDIA |
11136            types::LeAudioContextType::LIVE | types::LeAudioContextType::NOTIFICATIONS)
11137                   .value();
11138   supported_snk_context_types_ =
11139           available_snk_context_types_ |
11140           types::AudioContexts(types::LeAudioContextType::UNSPECIFIED).value();
11141   available_src_context_types_ = available_snk_context_types_;
11142   supported_src_context_types_ =
11143           available_src_context_types_ |
11144           types::AudioContexts(types::LeAudioContextType::UNSPECIFIED).value();
11145 
11146   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationAnyLeft,
11147                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
11148                                 default_channel_cnt, 0x0024, false /*add_csis*/, true /*add_cas*/,
11149                                 true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
11150                                 0 /*rank*/);
11151   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11152               OnConnectionState(ConnectionState::CONNECTED, test_address0))
11153           .Times(1);
11154   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11155               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
11156           .WillOnce(DoAll(SaveArg<1>(&group_id)));
11157 
11158   ConnectLeAudio(test_address0);
11159   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
11160 
11161   // Audio sessions are started only when device gets active
11162   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
11163   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
11164   LeAudioClient::Get()->GroupSetActive(group_id);
11165   SyncOnMainLoop();
11166   EXPECT_CALL(mock_state_machine_,
11167               StartStream(_, bluetooth::le_audio::types::LeAudioContextType::MEDIA, _, _))
11168           .Times(1);
11169   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
11170   SyncOnMainLoop();
11171   Mock::VerifyAndClearExpectations(&mock_state_machine_);
11172 
11173   auto group = streaming_groups.at(group_id);
11174 
11175   stay_at_qos_config_in_start_stream = true;
11176   log::info("Reconfigure to conversational and stay in Codec Config");
11177 
11178   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(1);
11179   EXPECT_CALL(mock_state_machine_, ConfigureStream(_, _, _, _, _)).Times(1);
11180 
11181   LeAudioClient::Get()->SetInCall(true);
11182   SyncOnMainLoop();
11183 
11184   ASSERT_TRUE(group->GetState() == types::AseState::BTA_LE_AUDIO_ASE_STATE_CODEC_CONFIGURED);
11185 
11186   log::info("Expect not action on metadata change");
11187 
11188   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(0);
11189   EXPECT_CALL(mock_state_machine_, ConfigureStream(_, _, _, _, _)).Times(0);
11190 
11191   UpdateLocalSourceMetadata(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC);
11192   SyncOnMainLoop();
11193   Mock::VerifyAndClearExpectations(&mock_state_machine_);
11194 }
11195 
TEST_F(UnicastTest,MusicDuringCallContextTypes_SpeedUpReconfigFlagEnabled)11196 TEST_F(UnicastTest, MusicDuringCallContextTypes_SpeedUpReconfigFlagEnabled) {
11197   const RawAddress test_address0 = GetTestAddress(0);
11198   int group_id = bluetooth::groups::kGroupUnknown;
11199 
11200   available_snk_context_types_ =
11201           (types::LeAudioContextType::CONVERSATIONAL | types::LeAudioContextType::RINGTONE |
11202            types::LeAudioContextType::GAME | types::LeAudioContextType::MEDIA |
11203            types::LeAudioContextType::LIVE | types::LeAudioContextType::NOTIFICATIONS)
11204                   .value();
11205   supported_snk_context_types_ =
11206           available_snk_context_types_ |
11207           types::AudioContexts(types::LeAudioContextType::UNSPECIFIED).value();
11208   available_src_context_types_ = available_snk_context_types_;
11209   supported_src_context_types_ =
11210           available_src_context_types_ |
11211           types::AudioContexts(types::LeAudioContextType::UNSPECIFIED).value();
11212 
11213   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationAnyLeft,
11214                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
11215                                 default_channel_cnt, 0x0024, false /*add_csis*/, true /*add_cas*/,
11216                                 true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
11217                                 0 /*rank*/);
11218   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11219               OnConnectionState(ConnectionState::CONNECTED, test_address0))
11220           .Times(1);
11221   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11222               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
11223           .WillOnce(DoAll(SaveArg<1>(&group_id)));
11224 
11225   ConnectLeAudio(test_address0);
11226   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
11227 
11228   // Audio sessions are started only when device gets active
11229   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
11230   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
11231   LeAudioClient::Get()->GroupSetActive(group_id);
11232   SyncOnMainLoop();
11233 
11234   log::info("Step 1 Start with the call first");
11235   // -----------------------------
11236   // CONVERSATIONAL is from In Call preference, and RINGTONE is from metadata
11237   LeAudioClient::Get()->SetInCall(true);
11238   types::BidirectionalPair<types::AudioContexts> contexts = {
11239           .sink = types::AudioContexts(types::LeAudioContextType::RINGTONE |
11240                                        types::LeAudioContextType::CONVERSATIONAL),
11241           .source = types::AudioContexts(types::LeAudioContextType::CONVERSATIONAL)};
11242   EXPECT_CALL(mock_state_machine_,
11243               StartStream(_, bluetooth::le_audio::types::LeAudioContextType::CONVERSATIONAL,
11244                           contexts, _))
11245           .Times(1);
11246   StartStreaming(AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE, AUDIO_CONTENT_TYPE_UNKNOWN, group_id);
11247   LocalAudioSourceResume();
11248   LocalAudioSinkResume();
11249 
11250   // Verify
11251   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
11252   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
11253   Mock::VerifyAndClearExpectations(&mock_state_machine_);
11254 
11255   // Verify Data transfer
11256   uint8_t cis_count_out = 1;
11257   uint8_t cis_count_in = 1;
11258   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 40);
11259 
11260   log::info("Step  2) Start MEDIA during the call, expect MEDIA only on the remote sink");
11261 
11262   contexts = {.sink = types::AudioContexts(types::LeAudioContextType::CONVERSATIONAL |
11263                                            types::LeAudioContextType::MEDIA),
11264               .source = types::AudioContexts(types::LeAudioContextType::CONVERSATIONAL)};
11265   EXPECT_CALL(mock_state_machine_,
11266               StartStream(_, bluetooth::le_audio::types::LeAudioContextType::CONVERSATIONAL,
11267                           contexts, _))
11268           .Times(1);
11269   UpdateLocalSourceMetadata(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, false);
11270   SyncOnMainLoop();
11271 
11272   Mock::VerifyAndClearExpectations(&mock_state_machine_);
11273   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
11274   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
11275 
11276   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(0);
11277   contexts = {.sink = types::AudioContexts(types::LeAudioContextType::MEDIA |
11278                                            types::LeAudioContextType::CONVERSATIONAL),
11279               .source = types::AudioContexts(types::LeAudioContextType::CONVERSATIONAL)};
11280   EXPECT_CALL(mock_state_machine_,
11281               StartStream(_, types::LeAudioContextType::CONVERSATIONAL, contexts, _))
11282           .Times(1);
11283   UpdateLocalSourceMetadata(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC,
11284                             /*reconfigure=*/false);
11285   Mock::VerifyAndClearExpectations(&mock_state_machine_);
11286   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
11287   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
11288 
11289   log::info("Step 3) Disable call so we could go back to MEDIA");
11290   // ---------------------------------------
11291   // Suspend should stop the stream
11292   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(1);
11293   LocalAudioSourceSuspend();
11294   LocalAudioSinkSuspend();
11295   // simulate suspend timeout passed, alarm executing
11296   fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
11297 
11298   LeAudioClient::Get()->SetInCall(false);
11299   SyncOnMainLoop();
11300   Mock::VerifyAndClearExpectations(&mock_state_machine_);
11301 
11302   // Restart the stream with MEDIA
11303   contexts = {.sink = types::AudioContexts(types::LeAudioContextType::MEDIA),
11304               .source = types::AudioContexts()};
11305   EXPECT_CALL(mock_state_machine_, StartStream(_, types::LeAudioContextType::MEDIA, contexts, _))
11306           .Times(1);
11307   UpdateLocalSourceMetadata(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC,
11308                             /*reconfigure=*/false);
11309   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
11310   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
11311 
11312   /* The source needs to resume to reconfigure to MEDIA */
11313   LocalAudioSourceResume(/*expect_confirm=*/false);
11314   LocalAudioSourceResume(/*expect_confirm=*/true);
11315   Mock::VerifyAndClearExpectations(&mock_state_machine_);
11316   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
11317   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
11318 
11319   log::info("Step 3) Stop streaming");
11320 
11321   // ------------------
11322   StopStreaming(group_id);
11323   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
11324 
11325   // Release
11326   EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop()).Times(1);
11327   EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(1);
11328   EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(1);
11329   do_in_main_thread(base::BindOnce(
11330           [](LeAudioClient* client) { client->GroupSetActive(bluetooth::groups::kGroupUnknown); },
11331           LeAudioClient::Get()));
11332   SyncOnMainLoop();
11333 }
11334 
11335 /* When a certain context is unavailable but supported we should not stream that
11336  * context - either stop the stream or eliminate this strim from the mix
11337  * This could be na IOP issue so continue streaming (and reconfigure if needed
11338  * for that use case).
11339  * Since the unavailable context is supported, do not put this context into
11340  * the metadata, and do not replace it with UNSPECIFIED.
11341  */
TEST_F(UnicastTest,StartNotAvailableSupportedContextType)11342 TEST_F(UnicastTest, StartNotAvailableSupportedContextType) {
11343   const RawAddress test_address0 = GetTestAddress(0);
11344   int group_id = bluetooth::groups::kGroupUnknown;
11345 
11346   // EMERGENCYALARM is not available, but supported
11347   available_snk_context_types_ =
11348           (types::LeAudioContextType::RINGTONE | types::LeAudioContextType::CONVERSATIONAL |
11349            types::LeAudioContextType::UNSPECIFIED | types::LeAudioContextType::MEDIA)
11350                   .value();
11351   available_src_context_types_ = available_snk_context_types_;
11352   supported_snk_context_types_ = types::kLeAudioContextAllTypes.value();
11353   supported_src_context_types_ =
11354           (types::kLeAudioContextAllRemoteSource | types::LeAudioContextType::UNSPECIFIED).value();
11355 
11356   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
11357                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
11358                                 default_channel_cnt, 0x0004, false /*add_csis*/, true /*add_cas*/,
11359                                 true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
11360                                 0 /*rank*/);
11361   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11362               OnConnectionState(ConnectionState::CONNECTED, test_address0))
11363           .Times(1);
11364   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11365               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
11366           .WillOnce(DoAll(SaveArg<1>(&group_id)));
11367 
11368   ConnectLeAudio(test_address0);
11369   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
11370 
11371   // Expect configuring to (or staying with) the right configuration but the
11372   // metadata should not get the EMERGENCYALARM context, nor the UNSPECIFIED
11373   // Since the initial config is UNSPECIFIED, then even for sonification events
11374   // we should reconfigure to less generic EMERGENCYALARM scenario
11375   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
11376   types::BidirectionalPair<types::AudioContexts> metadata = {.sink = types::AudioContexts(),
11377                                                              .source = types::AudioContexts()};
11378   EXPECT_CALL(mock_state_machine_,
11379               StartStream(_, types::LeAudioContextType::EMERGENCYALARM, metadata, _))
11380           .Times(0);
11381 
11382   LeAudioClient::Get()->GroupSetActive(group_id);
11383   SyncOnMainLoop();
11384 
11385   StartStreaming(AUDIO_USAGE_EMERGENCY, AUDIO_CONTENT_TYPE_UNKNOWN, group_id, AUDIO_SOURCE_INVALID,
11386                  false, false);
11387 
11388   SyncOnMainLoop();
11389   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
11390   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
11391 }
11392 
11393 /* When a certain context is unavailable and not supported and the UNSPECIFIED
11394  * is not available we should stop the stream.
11395  * For now, stream will not be started in such a case.
11396  * In future we should be able to eliminate this context from the track mix.
11397  */
TEST_F(UnicastTest,StartNotAvailableUnsupportedContextTypeUnspecifiedUnavail)11398 TEST_F(UnicastTest, StartNotAvailableUnsupportedContextTypeUnspecifiedUnavail) {
11399   const RawAddress test_address0 = GetTestAddress(0);
11400   int group_id = bluetooth::groups::kGroupUnknown;
11401 
11402   // EMERGENCYALARM is not available, nor supported
11403   available_snk_context_types_ =
11404           (types::LeAudioContextType::RINGTONE | types::LeAudioContextType::CONVERSATIONAL |
11405            types::LeAudioContextType::MEDIA)
11406                   .value();
11407   available_src_context_types_ = available_snk_context_types_;
11408   supported_snk_context_types_ =
11409           (available_snk_context_types_ | types::LeAudioContextType::UNSPECIFIED).value();
11410   supported_src_context_types_ =
11411           (available_src_context_types_ | types::LeAudioContextType::UNSPECIFIED).value();
11412 
11413   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
11414                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
11415                                 default_channel_cnt, 0x0004, false /*add_csis*/, true /*add_cas*/,
11416                                 true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
11417                                 0 /*rank*/);
11418   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11419               OnConnectionState(ConnectionState::CONNECTED, test_address0))
11420           .Times(1);
11421   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11422               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
11423           .WillOnce(DoAll(SaveArg<1>(&group_id)));
11424 
11425   ConnectLeAudio(test_address0);
11426   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
11427 
11428   // Expect configuring to the default config since the EMERGENCYALARM is
11429   // not on the list of supported contexts and UNSPECIFIED should not be
11430   // in the metadata as it is unavailable.
11431   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
11432   types::BidirectionalPair<types::AudioContexts> metadata = {.sink = types::AudioContexts(),
11433                                                              .source = types::AudioContexts()};
11434   EXPECT_CALL(mock_state_machine_,
11435               StartStream(_, types::LeAudioContextType::EMERGENCYALARM, metadata, _))
11436           .Times(0);
11437 
11438   LeAudioClient::Get()->GroupSetActive(group_id);
11439   SyncOnMainLoop();
11440 
11441   StartStreaming(AUDIO_USAGE_EMERGENCY, AUDIO_CONTENT_TYPE_UNKNOWN, group_id, AUDIO_SOURCE_INVALID,
11442                  false, false);
11443 
11444   SyncOnMainLoop();
11445   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
11446   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
11447 }
11448 
11449 /* This test verifies if we use UNSPCIFIED context when another context is
11450  * unavailable and not supported but UNSPCIFIED is in available audio contexts.
11451  */
TEST_F(UnicastTest,StartNotAvailableUnsupportedContextTypeUnspecifiedAvail)11452 TEST_F(UnicastTest, StartNotAvailableUnsupportedContextTypeUnspecifiedAvail) {
11453   const RawAddress test_address0 = GetTestAddress(0);
11454   int group_id = bluetooth::groups::kGroupUnknown;
11455 
11456   // EMERGENCYALARM is not available, nor supported
11457   available_snk_context_types_ =
11458           (types::LeAudioContextType::RINGTONE | types::LeAudioContextType::CONVERSATIONAL |
11459            types::LeAudioContextType::UNSPECIFIED | types::LeAudioContextType::MEDIA)
11460                   .value();
11461   available_src_context_types_ = available_snk_context_types_;
11462   supported_snk_context_types_ = available_snk_context_types_;
11463   supported_src_context_types_ = available_src_context_types_;
11464 
11465   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
11466                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
11467                                 default_channel_cnt, 0x0004, false /*add_csis*/, true /*add_cas*/,
11468                                 true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
11469                                 0 /*rank*/);
11470   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11471               OnConnectionState(ConnectionState::CONNECTED, test_address0))
11472           .Times(1);
11473   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11474               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
11475           .WillOnce(DoAll(SaveArg<1>(&group_id)));
11476 
11477   ConnectLeAudio(test_address0);
11478   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
11479 
11480   // Expect configuring to the default config since the EMERGENCYALARM is
11481   // not on the list of supported contexts and UNSPECIFIED will be used in
11482   // the metadata.
11483   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
11484   types::BidirectionalPair<types::AudioContexts> metadata = {
11485           .sink = types::AudioContexts(types::LeAudioContextType::UNSPECIFIED),
11486           .source = types::AudioContexts()};
11487   EXPECT_CALL(mock_state_machine_,
11488               StartStream(_, types::LeAudioContextType::EMERGENCYALARM, metadata, _))
11489           .Times(1);
11490 
11491   LeAudioClient::Get()->GroupSetActive(group_id);
11492   SyncOnMainLoop();
11493 
11494   StartStreaming(AUDIO_USAGE_EMERGENCY, AUDIO_CONTENT_TYPE_UNKNOWN, group_id);
11495 
11496   SyncOnMainLoop();
11497   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
11498   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
11499 
11500   // Verify Data transfer on one audio source cis
11501   uint8_t cis_count_out = 1;
11502   uint8_t cis_count_in = 0;
11503   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
11504 }
11505 
TEST_F(UnicastTest,NotifyAboutGroupTunrnedIdleEnabled)11506 TEST_F(UnicastTest, NotifyAboutGroupTunrnedIdleEnabled) {
11507   const RawAddress test_address0 = GetTestAddress(0);
11508   int group_id = bluetooth::groups::kGroupUnknown;
11509 
11510   osi_property_set_bool(kNotifyUpperLayerAboutGroupBeingInIdleDuringCall, true);
11511 
11512   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
11513                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
11514                                 default_channel_cnt, 0x0004, false /*add_csis*/, true /*add_cas*/,
11515                                 true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
11516                                 0 /*rank*/);
11517   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11518               OnConnectionState(ConnectionState::CONNECTED, test_address0))
11519           .Times(1);
11520   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11521               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
11522           .WillOnce(DoAll(SaveArg<1>(&group_id)));
11523 
11524   ConnectLeAudio(test_address0);
11525   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
11526 
11527   // Start streaming
11528   uint8_t cis_count_out = 1;
11529   uint8_t cis_count_in = 0;
11530 
11531   LeAudioClient::Get()->SetInCall(true);
11532 
11533   // Audio sessions are started only when device gets active
11534   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
11535   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
11536   LeAudioClient::Get()->GroupSetActive(group_id);
11537   SyncOnMainLoop();
11538 
11539   StartStreaming(AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE, AUDIO_CONTENT_TYPE_UNKNOWN, group_id);
11540 
11541   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
11542   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
11543   SyncOnMainLoop();
11544 
11545   // Verify Data transfer on one audio source cis
11546   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
11547 
11548   // Release
11549 
11550   /* To be called twice
11551    * 1. GroupStatus::INACTIVE
11552    * 2. GroupStatus::TURNED_IDLE_DURING_CALL
11553    */
11554   EXPECT_CALL(mock_audio_hal_client_callbacks_, OnGroupStatus(group_id, _)).Times(2);
11555 
11556   EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop()).Times(1);
11557   EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(1);
11558   EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(1);
11559 
11560   do_in_main_thread(base::BindOnce(
11561           [](LeAudioClient* client) { client->GroupSetActive(bluetooth::groups::kGroupUnknown); },
11562           LeAudioClient::Get()));
11563 
11564   SyncOnMainLoop();
11565   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
11566 
11567   LeAudioClient::Get()->SetInCall(false);
11568   osi_property_set_bool(kNotifyUpperLayerAboutGroupBeingInIdleDuringCall, false);
11569 }
11570 
TEST_F(UnicastTest,NotifyAboutGroupTunrnedIdleDisabled)11571 TEST_F(UnicastTest, NotifyAboutGroupTunrnedIdleDisabled) {
11572   const RawAddress test_address0 = GetTestAddress(0);
11573   int group_id = bluetooth::groups::kGroupUnknown;
11574 
11575   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
11576                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
11577                                 default_channel_cnt, 0x0004, false /*add_csis*/, true /*add_cas*/,
11578                                 true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
11579                                 0 /*rank*/);
11580   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11581               OnConnectionState(ConnectionState::CONNECTED, test_address0))
11582           .Times(1);
11583   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11584               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
11585           .WillOnce(DoAll(SaveArg<1>(&group_id)));
11586 
11587   ConnectLeAudio(test_address0);
11588   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
11589 
11590   // Start streaming
11591   uint8_t cis_count_out = 1;
11592   uint8_t cis_count_in = 0;
11593 
11594   LeAudioClient::Get()->SetInCall(true);
11595 
11596   // Audio sessions are started only when device gets active
11597   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
11598   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
11599   LeAudioClient::Get()->GroupSetActive(group_id);
11600   SyncOnMainLoop();
11601 
11602   StartStreaming(AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE, AUDIO_CONTENT_TYPE_UNKNOWN, group_id);
11603 
11604   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
11605   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
11606   SyncOnMainLoop();
11607 
11608   // Verify Data transfer on one audio source cis
11609   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
11610 
11611   // Release
11612 
11613   /* To be called once only
11614    * 1. GroupStatus::INACTIVE
11615    */
11616   EXPECT_CALL(mock_audio_hal_client_callbacks_, OnGroupStatus(group_id, _)).Times(1);
11617 
11618   EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop()).Times(1);
11619   EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(1);
11620   EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(1);
11621 
11622   do_in_main_thread(base::BindOnce(
11623           [](LeAudioClient* client) { client->GroupSetActive(bluetooth::groups::kGroupUnknown); },
11624           LeAudioClient::Get()));
11625 
11626   SyncOnMainLoop();
11627   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
11628 
11629   LeAudioClient::Get()->SetInCall(false);
11630 }
11631 
TEST_F(UnicastTest,HandleDatabaseOutOfSync)11632 TEST_F(UnicastTest, HandleDatabaseOutOfSync) {
11633   const RawAddress test_address0 = GetTestAddress(0);
11634   int group_id = bluetooth::groups::kGroupUnknown;
11635 
11636   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
11637                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
11638                                 default_channel_cnt, 0x0004, false /*add_csis*/, true /*add_cas*/,
11639                                 true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
11640                                 0 /*rank*/);
11641   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11642               OnConnectionState(ConnectionState::CONNECTED, test_address0))
11643           .Times(1);
11644   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11645               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
11646           .WillOnce(DoAll(SaveArg<1>(&group_id)));
11647 
11648   ConnectLeAudio(test_address0);
11649   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
11650 
11651   SyncOnMainLoop();
11652   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
11653 
11654   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11655               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
11656           .Times(1);
11657   InjectDisconnectedEvent(1, GATT_CONN_TERMINATE_PEER_USER);
11658   SyncOnMainLoop();
11659   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
11660   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
11661 
11662   /* Simulate DATABASE OUT OF SYNC */
11663   ccc_stored_byte_val_ = 0x01;
11664   gatt_read_ctp_ccc_status_ = GATT_DATABASE_OUT_OF_SYNC;
11665 
11666   EXPECT_CALL(mock_gatt_queue_, WriteDescriptor(_, _, _, _, _, _)).Times(0);
11667   ON_CALL(mock_gatt_interface_, ServiceSearchRequest(_, _)).WillByDefault(Return());
11668   EXPECT_CALL(mock_gatt_interface_, ServiceSearchRequest(_, _));
11669 
11670   InjectConnectedEvent(test_address0, 1);
11671   SyncOnMainLoop();
11672   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
11673   Mock::VerifyAndClearExpectations(&mock_gatt_queue_);
11674 }
11675 
TEST_F(UnicastTest,TestRemoteDeviceKeepCccValues)11676 TEST_F(UnicastTest, TestRemoteDeviceKeepCccValues) {
11677   const RawAddress test_address0 = GetTestAddress(0);
11678   int group_id = bluetooth::groups::kGroupUnknown;
11679 
11680   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
11681                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
11682                                 default_channel_cnt, 0x0004, false /*add_csis*/, true /*add_cas*/,
11683                                 true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
11684                                 0 /*rank*/);
11685   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11686               OnConnectionState(ConnectionState::CONNECTED, test_address0))
11687           .Times(1);
11688   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11689               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
11690           .WillOnce(DoAll(SaveArg<1>(&group_id)));
11691 
11692   ConnectLeAudio(test_address0);
11693   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
11694 
11695   SyncOnMainLoop();
11696   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
11697 
11698   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11699               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
11700           .Times(1);
11701   InjectDisconnectedEvent(1, GATT_CONN_TERMINATE_PEER_USER);
11702   SyncOnMainLoop();
11703   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
11704   Mock::VerifyAndClearExpectations(&mock_gatt_queue_);
11705 
11706   /* Simulate remote cache is good */
11707   ccc_stored_byte_val_ = 0x01;
11708 
11709   EXPECT_CALL(mock_gatt_queue_, WriteDescriptor(_, _, _, _, _, _)).Times(0);
11710   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11711               OnConnectionState(ConnectionState::CONNECTED, test_address0))
11712           .Times(1);
11713 
11714   InjectConnectedEvent(test_address0, 1);
11715   SyncOnMainLoop();
11716   Mock::VerifyAndClearExpectations(&mock_gatt_queue_);
11717   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
11718 }
11719 
TEST_F(UnicastTest,TestRemoteDeviceForgetsCccValues)11720 TEST_F(UnicastTest, TestRemoteDeviceForgetsCccValues) {
11721   const RawAddress test_address0 = GetTestAddress(0);
11722   int group_id = bluetooth::groups::kGroupUnknown;
11723 
11724   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
11725                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
11726                                 default_channel_cnt, 0x0004, false /*add_csis*/, true /*add_cas*/,
11727                                 true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
11728                                 0 /*rank*/);
11729   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11730               OnConnectionState(ConnectionState::CONNECTED, test_address0))
11731           .Times(1);
11732   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11733               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
11734           .WillOnce(DoAll(SaveArg<1>(&group_id)));
11735 
11736   ConnectLeAudio(test_address0);
11737   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
11738 
11739   SyncOnMainLoop();
11740   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
11741 
11742   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11743               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
11744           .Times(1);
11745   InjectDisconnectedEvent(1, GATT_CONN_TERMINATE_PEER_USER);
11746   SyncOnMainLoop();
11747   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
11748   Mock::VerifyAndClearExpectations(&mock_gatt_queue_);
11749 
11750   /* Simulate remote cache is broken */
11751   ccc_stored_byte_val_ = 0;
11752   EXPECT_CALL(mock_gatt_queue_, WriteDescriptor(_, _, _, _, _, _)).Times(AtLeast(1));
11753   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11754               OnConnectionState(ConnectionState::CONNECTED, test_address0))
11755           .Times(1);
11756 
11757   InjectConnectedEvent(test_address0, 1);
11758   SyncOnMainLoop();
11759   Mock::VerifyAndClearExpectations(&mock_gatt_queue_);
11760   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
11761 }
11762 
TEST_F(UnicastTest,SpeakerStreamingTimeout)11763 TEST_F(UnicastTest, SpeakerStreamingTimeout) {
11764   const RawAddress test_address0 = GetTestAddress(0);
11765   int group_id = bluetooth::groups::kGroupUnknown;
11766 
11767   SetSampleDatabaseEarbudsValid(
11768           1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
11769           codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt, default_channel_cnt, 0x0004,
11770           /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/, true /*add_pacs*/,
11771           default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
11772   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11773               OnConnectionState(ConnectionState::CONNECTED, test_address0))
11774           .Times(1);
11775   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11776               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
11777           .WillOnce(DoAll(SaveArg<1>(&group_id)));
11778 
11779   ConnectLeAudio(test_address0);
11780   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
11781 
11782   // Start streaming
11783   uint8_t cis_count_out = 1;
11784   uint8_t cis_count_in = 0;
11785 
11786   // Audio sessions are started only when device gets active
11787   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
11788   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
11789   LeAudioClient::Get()->GroupSetActive(group_id);
11790   SyncOnMainLoop();
11791 
11792   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
11793 
11794   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
11795   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
11796   SyncOnMainLoop();
11797 
11798   // Verify Data transfer on one audio source cis
11799   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
11800 
11801   auto group = streaming_groups.at(group_id);
11802   auto device = group->GetFirstActiveDevice();
11803 
11804   // Do not accept direct connect, but expect it to arrive.
11805   ON_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_DIRECT_CONNECTION, _)).WillByDefault(Return());
11806 
11807   EXPECT_CALL(mock_btm_interface_, AclDisconnectFromHandle(device->conn_id_, _)).Times(1);
11808   ON_CALL(mock_btm_interface_, AclDisconnectFromHandle(_, _))
11809           .WillByDefault([](uint16_t handle, tHCI_STATUS /*rs*/) {
11810             ASSERT_NE(handle, GATT_INVALID_CONN_ID);
11811             // Do nothing here now.
11812           });
11813 
11814   state_machine_callbacks_->OnStateTransitionTimeout(group_id);
11815   SyncOnMainLoop();
11816   ASSERT_EQ(device->GetConnectionState(), DeviceConnectState::DISCONNECTING_AND_RECOVER);
11817 
11818   InjectDisconnectedEvent(device->conn_id_, GATT_CONN_TERMINATE_LOCAL_HOST);
11819   SyncOnMainLoop();
11820 
11821   /* No assigned cises should remain when transition remains in IDLE state */
11822   ASSERT_NE(0lu, streaming_groups.count(group_id));
11823   ASSERT_EQ(0, static_cast<int>(group->cig.cises.size()));
11824   ASSERT_TRUE(device != nullptr);
11825   ASSERT_EQ(device->GetConnectionState(), DeviceConnectState::CONNECTING_AUTOCONNECT);
11826   Mock::VerifyAndClearExpectations(&mock_btm_interface_);
11827 }
11828 
TEST_F(UnicastTest,AddMemberToAllowListWhenOneDeviceConnected)11829 TEST_F(UnicastTest, AddMemberToAllowListWhenOneDeviceConnected) {
11830   uint8_t group_size = 2;
11831   int group_id = 2;
11832   int conn_id_dev_0 = 1;
11833   int conn_id_dev_1 = 2;
11834 
11835   /*Scenario to test
11836    * 1. Connect Device A and disconnect
11837    * 2. Connect Device B
11838    * 3. verify Device B is in the allow list with direct connect.
11839    */
11840   // Report working CSIS
11841   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
11842 
11843   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
11844           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
11845 
11846   // First earbud
11847   const RawAddress test_address0 = GetTestAddress(0);
11848   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
11849 
11850   ConnectCsisDevice(test_address0, conn_id_dev_0, codec_spec_conf::kLeAudioLocationFrontLeft,
11851                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
11852 
11853   SyncOnMainLoop();
11854 
11855   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, _)).Times(1);
11856   EXPECT_CALL(mock_gatt_interface_,
11857               Open(gatt_if, test_address0, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _))
11858           .Times(1);
11859 
11860   InjectDisconnectedEvent(conn_id_dev_0);
11861 
11862   SyncOnMainLoop();
11863   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
11864 
11865   // Second earbud
11866   const RawAddress test_address1 = GetTestAddress(1);
11867   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
11868 
11869   /* Do not connect first  device but expect Open will arrive.*/
11870   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, false)).Times(1);
11871   EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address0, BTM_BLE_DIRECT_CONNECTION, _))
11872           .Times(1);
11873   ON_CALL(mock_gatt_interface_, Open(_, test_address0, BTM_BLE_DIRECT_CONNECTION, _))
11874           .WillByDefault(Return());
11875 
11876   ConnectCsisDevice(test_address1, conn_id_dev_1, codec_spec_conf::kLeAudioLocationFrontRight,
11877                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
11878                     true /*connect_through_csis*/);
11879 
11880   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
11881 }
11882 
TEST_F(UnicastTest,ResetToDefaultReconnectionMode)11883 TEST_F(UnicastTest, ResetToDefaultReconnectionMode) {
11884   uint8_t group_size = 2;
11885   int group_id = 2;
11886   int conn_id_dev_0 = 1;
11887   int conn_id_dev_1 = 2;
11888 
11889   /*Scenario to test
11890    * 1. Connect Device A and disconnect
11891    * 2. Connect Device B
11892    * 3. verify Device B is in the allow list.
11893    * 4. Disconnect B device
11894    * 5, Verify A and B device are back in targeted announcement reconnection
11895    * mode
11896    */
11897   // Report working CSIS
11898   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
11899 
11900   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
11901           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
11902 
11903   // First earbud
11904   const RawAddress test_address0 = GetTestAddress(0);
11905   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
11906 
11907   ConnectCsisDevice(test_address0, conn_id_dev_0, codec_spec_conf::kLeAudioLocationFrontLeft,
11908                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
11909 
11910   SyncOnMainLoop();
11911 
11912   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, _)).Times(1);
11913   EXPECT_CALL(mock_gatt_interface_,
11914               Open(gatt_if, test_address0, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _))
11915           .Times(1);
11916 
11917   InjectDisconnectedEvent(conn_id_dev_0);
11918 
11919   SyncOnMainLoop();
11920   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
11921 
11922   // Second earbud
11923   const RawAddress test_address1 = GetTestAddress(1);
11924   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
11925 
11926   /* Verify first earbud will start doing direct connect first */
11927   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, false)).Times(1);
11928   ON_CALL(mock_gatt_interface_, Open(_, test_address0, BTM_BLE_DIRECT_CONNECTION, _))
11929           .WillByDefault(Return());
11930   EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address0, BTM_BLE_DIRECT_CONNECTION, _))
11931           .Times(1);
11932 
11933   ConnectCsisDevice(test_address1, conn_id_dev_1, codec_spec_conf::kLeAudioLocationFrontRight,
11934                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
11935                     true /*connect_through_csis*/);
11936 
11937   SyncOnMainLoop();
11938   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
11939 
11940   // Disconnect Device B, expect default reconnection mode for Device A.
11941   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, false)).Times(1);
11942   EXPECT_CALL(mock_gatt_interface_,
11943               Open(gatt_if, test_address0, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _))
11944           .Times(1);
11945   EXPECT_CALL(mock_gatt_interface_,
11946               Open(gatt_if, test_address1, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _))
11947           .Times(1);
11948   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address1, false)).Times(1);
11949 
11950   InjectDisconnectedEvent(conn_id_dev_1, GATT_CONN_TERMINATE_PEER_USER);
11951   SyncOnMainLoop();
11952 
11953   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
11954 }
11955 
TEST_F(UnicastTest,DisconnectAclBeforeGettingReadResponses)11956 TEST_F(UnicastTest, DisconnectAclBeforeGettingReadResponses) {
11957   uint8_t group_size = 2;
11958   int group_id = 2;
11959 
11960   // Report working CSIS
11961   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
11962 
11963   const RawAddress test_address0 = GetTestAddress(0);
11964   const RawAddress test_address1 = GetTestAddress(1);
11965 
11966   /* Due to imitated problems with GATT read operations (status != GATT_SUCCESS)
11967    * a CONNECTED state should not be propagated together with audio location
11968    */
11969   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11970               OnConnectionState(ConnectionState::CONNECTED, test_address0))
11971           .Times(0);
11972   EXPECT_CALL(mock_audio_hal_client_callbacks_,
11973               OnSinkAudioLocationAvailable(test_address0,
11974                                            std::make_optional<std::bitset<32>>(
11975                                                    codec_spec_conf::kLeAudioLocationFrontLeft)))
11976           .Times(0);
11977 
11978   // First earbud initial connection
11979   SetSampleDatabaseEarbudsValid(1 /* conn_id */, test_address0,
11980                                 codec_spec_conf::kLeAudioLocationFrontLeft,
11981                                 codec_spec_conf::kLeAudioLocationFrontLeft, default_channel_cnt,
11982                                 default_channel_cnt, 0x0004, /* source sample freq 16khz */
11983                                 true,                        /*add_csis*/
11984                                 true,                        /*add_cas*/
11985                                 true,                        /*add_pacs*/
11986                                 true,                        /*add_ascs*/
11987                                 group_size, 1 /* rank */, GATT_INTERNAL_ERROR);
11988   groups[test_address0] = group_id;
11989   // by default indicate link as encrypted
11990   ON_CALL(mock_btm_interface_, BTM_IsEncrypted(test_address0, _))
11991           .WillByDefault(DoAll(Return(true)));
11992 
11993   EXPECT_CALL(mock_gatt_interface_, Open(gatt_if, test_address0, BTM_BLE_DIRECT_CONNECTION, _))
11994           .Times(1);
11995   /* When connected it will got to TA */
11996   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, _)).Times(1);
11997   EXPECT_CALL(mock_gatt_interface_,
11998               Open(gatt_if, test_address0, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _))
11999           .Times(1);
12000 
12001   do_in_main_thread(base::BindOnce(&LeAudioClient::Connect, base::Unretained(LeAudioClient::Get()),
12002                                    test_address0));
12003 
12004   SyncOnMainLoop();
12005   Mock::VerifyAndClearExpectations(&mock_btm_interface_);
12006   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
12007   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
12008   InjectGroupDeviceAdded(test_address0, group_id);
12009 
12010   // Second earbud initial connection
12011   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12012               OnSinkAudioLocationAvailable(test_address1,
12013                                            std::make_optional<std::bitset<32>>(
12014                                                    codec_spec_conf::kLeAudioLocationFrontRight)))
12015           .Times(1);
12016 
12017   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
12018   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
12019                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
12020                     true /*connect_through_csis*/);
12021 
12022   Mock::VerifyAndClearExpectations(&mock_btif_storage_);
12023 
12024   /* for Target announcements AutoConnect is always there, until
12025    * device is removed
12026    */
12027   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, false)).Times(0);
12028   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, false)).Times(0);
12029 
12030   // Verify grouping information
12031   std::vector<RawAddress> devs = LeAudioClient::Get()->GetGroupDevices(group_id);
12032   ASSERT_NE(std::find(devs.begin(), devs.end(), test_address0), devs.end());
12033   ASSERT_NE(std::find(devs.begin(), devs.end(), test_address1), devs.end());
12034 
12035   /* Remove default action on the direct connect */
12036   ON_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_DIRECT_CONNECTION, _)).WillByDefault(Return());
12037 
12038   /* Initiate disconnection with timeout reason, the possible reason why GATT
12039    * read attribute operation may be not handled
12040    */
12041   InjectDisconnectedEvent(1, GATT_CONN_TIMEOUT);
12042   SyncOnMainLoop();
12043 
12044   /* After reconnection a sink audio location callback with connection state
12045    * should be propagated.
12046    */
12047   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12048               OnConnectionState(ConnectionState::CONNECTED, test_address0))
12049           .Times(1);
12050   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12051               OnSinkAudioLocationAvailable(test_address0,
12052                                            std::make_optional<std::bitset<32>>(
12053                                                    codec_spec_conf::kLeAudioLocationFrontLeft)))
12054           .Times(1);
12055 
12056   /* Prepare valid GATT status responsing attributes */
12057   SetSampleDatabaseEarbudsValid(1 /* conn_id */, test_address0,
12058                                 codec_spec_conf::kLeAudioLocationFrontLeft,
12059                                 codec_spec_conf::kLeAudioLocationFrontLeft, default_channel_cnt,
12060                                 default_channel_cnt, 0x0004, /* source sample freq 16khz */
12061                                 true,                        /*add_csis*/
12062                                 true,                        /*add_cas*/
12063                                 true,                        /*add_pacs*/
12064                                 true,                        /*add_ascs*/
12065                                 group_size, 1 /* rank */);
12066 
12067   /* For background connect, test needs to Inject Connected Event */
12068   InjectConnectedEvent(test_address0, 1);
12069   SyncOnMainLoop();
12070 }
12071 
TEST_F(UnicastTest,GroupStreamStatus)12072 TEST_F(UnicastTest, GroupStreamStatus) {
12073   int group_id = bluetooth::groups::kGroupUnknown;
12074 
12075   InSequence s;
12076 
12077   /* Check if all states are properly notified */
12078   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12079               OnGroupStreamStatus(group_id, GroupStreamStatus::IDLE))
12080           .Times(1);
12081   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::IDLE);
12082 
12083   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12084               OnGroupStreamStatus(group_id, GroupStreamStatus::STREAMING))
12085           .Times(1);
12086   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::STREAMING);
12087 
12088   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12089               OnGroupStreamStatus(group_id, GroupStreamStatus::IDLE))
12090           .Times(1);
12091   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::RELEASING);
12092 
12093   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12094               OnGroupStreamStatus(group_id, GroupStreamStatus::STREAMING))
12095           .Times(1);
12096   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::STREAMING);
12097 
12098   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12099               OnGroupStreamStatus(group_id, GroupStreamStatus::IDLE))
12100           .Times(1);
12101   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::RELEASING_AUTONOMOUS);
12102 
12103   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12104               OnGroupStreamStatus(group_id, GroupStreamStatus::STREAMING))
12105           .Times(1);
12106   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::STREAMING);
12107 
12108   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12109               OnGroupStreamStatus(group_id, GroupStreamStatus::IDLE))
12110           .Times(1);
12111   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::SUSPENDING);
12112 
12113   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12114               OnGroupStreamStatus(group_id, GroupStreamStatus::STREAMING))
12115           .Times(1);
12116   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::STREAMING);
12117 
12118   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12119               OnGroupStreamStatus(group_id, GroupStreamStatus::IDLE))
12120           .Times(1);
12121   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::SUSPENDED);
12122 
12123   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12124               OnGroupStreamStatus(group_id, GroupStreamStatus::STREAMING))
12125           .Times(1);
12126   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::STREAMING);
12127 
12128   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12129               OnGroupStreamStatus(group_id, GroupStreamStatus::IDLE))
12130           .Times(1);
12131   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::CONFIGURED_AUTONOMOUS);
12132 
12133   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12134               OnGroupStreamStatus(group_id, GroupStreamStatus::STREAMING))
12135           .Times(1);
12136   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::STREAMING);
12137 
12138   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12139               OnGroupStreamStatus(group_id, GroupStreamStatus::IDLE))
12140           .Times(1);
12141   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::CONFIGURED_BY_USER);
12142 
12143   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12144               OnGroupStreamStatus(group_id, GroupStreamStatus::STREAMING))
12145           .Times(1);
12146   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::STREAMING);
12147 
12148   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12149               OnGroupStreamStatus(group_id, GroupStreamStatus::IDLE))
12150           .Times(1);
12151   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::DESTROYED);
12152 
12153   /* Check if there are no resending of the same state */
12154   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::RELEASING);
12155   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::SUSPENDING);
12156   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::SUSPENDED);
12157   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::CONFIGURED_AUTONOMOUS);
12158   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::CONFIGURED_BY_USER);
12159   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::IDLE);
12160 
12161   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12162               OnGroupStreamStatus(group_id, GroupStreamStatus::STREAMING))
12163           .Times(1);
12164   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::STREAMING);
12165   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::STREAMING);
12166 }
12167 
TEST_F(UnicastTest,GroupStreamStatusManyGroups)12168 TEST_F(UnicastTest, GroupStreamStatusManyGroups) {
12169   uint8_t group_size = 2;
12170   int group_id_1 = 1;
12171   int group_id_2 = 2;
12172 
12173   // Report working CSIS
12174   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
12175 
12176   ON_CALL(mock_csis_client_module_, GetDesiredSize(_)).WillByDefault(Return(group_size));
12177 
12178   // First group - First earbud
12179   const RawAddress test_address0 = GetTestAddress(0);
12180   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
12181   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
12182                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id_1,
12183                     1 /* rank*/);
12184 
12185   // First group - Second earbud
12186   const RawAddress test_address1 = GetTestAddress(1);
12187   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
12188   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
12189                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id_1,
12190                     2 /* rank*/, true /*connect_through_csis*/);
12191 
12192   // Second group - First earbud
12193   const RawAddress test_address2 = GetTestAddress(2);
12194   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address2, true)).Times(1);
12195   ConnectCsisDevice(test_address2, 3 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
12196                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id_2,
12197                     1 /* rank*/);
12198 
12199   // Second group - Second earbud
12200   const RawAddress test_address3 = GetTestAddress(3);
12201   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address3, true)).Times(1);
12202   ConnectCsisDevice(test_address3, 4 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
12203                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id_2,
12204                     2 /* rank*/, true /*connect_through_csis*/);
12205 
12206   InSequence s;
12207 
12208   // Group 1 IDLE
12209   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12210               OnGroupStreamStatus(group_id_1, GroupStreamStatus::IDLE))
12211           .Times(1);
12212   state_machine_callbacks_->StatusReportCb(group_id_1, GroupStreamStatus::IDLE);
12213 
12214   // Group 2 IDLE
12215   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12216               OnGroupStreamStatus(group_id_2, GroupStreamStatus::IDLE))
12217           .Times(1);
12218   state_machine_callbacks_->StatusReportCb(group_id_2, GroupStreamStatus::IDLE);
12219 
12220   log::info("Group 1 active and start streaming");
12221   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12222               OnGroupStreamStatus(group_id_1, GroupStreamStatus::STREAMING))
12223           .Times(1);
12224   LeAudioClient::Get()->GroupSetActive(group_id_1);
12225   SyncOnMainLoop();
12226   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id_1);
12227   SyncOnMainLoop();
12228   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
12229 
12230   log::info("Group 2 is getting active");
12231   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12232               OnGroupStreamStatus(group_id_1, GroupStreamStatus::IDLE))
12233           .Times(1);
12234   LeAudioClient::Get()->GroupSetActive(group_id_2);
12235   SyncOnMainLoop();
12236   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
12237 
12238   log::info("Group 2 is starts streaming");
12239   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12240               OnGroupStreamStatus(group_id_2, GroupStreamStatus::STREAMING))
12241           .Times(1);
12242   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id_2);
12243   SyncOnMainLoop();
12244   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
12245 }
12246 
TEST_F(UnicastTest,GroupStreamStatusManyGroups_GettingConfigWhileOtherGroupIsStreaming)12247 TEST_F(UnicastTest, GroupStreamStatusManyGroups_GettingConfigWhileOtherGroupIsStreaming) {
12248   uint8_t group_size = 2;
12249   int group_id_1 = 1;
12250   int group_id_2 = 2;
12251 
12252   // Report working CSIS
12253   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
12254 
12255   ON_CALL(mock_csis_client_module_, GetDesiredSize(_)).WillByDefault(Return(group_size));
12256 
12257   // First group - First earbud
12258   const RawAddress test_address0 = GetTestAddress(0);
12259   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
12260   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
12261                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id_1,
12262                     1 /* rank*/);
12263 
12264   // First group - Second earbud
12265   const RawAddress test_address1 = GetTestAddress(1);
12266   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
12267   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
12268                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id_1,
12269                     2 /* rank*/, true /*connect_through_csis*/);
12270 
12271   // Second group - First earbud
12272   const RawAddress test_address2 = GetTestAddress(2);
12273   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address2, true)).Times(1);
12274   ConnectCsisDevice(test_address2, 3 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
12275                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id_2,
12276                     1 /* rank*/);
12277 
12278   // Second group - Second earbud
12279   const RawAddress test_address3 = GetTestAddress(3);
12280   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address3, true)).Times(1);
12281   ConnectCsisDevice(test_address3, 4 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
12282                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id_2,
12283                     2 /* rank*/, true /*connect_through_csis*/);
12284 
12285   InSequence s;
12286 
12287   // Group 1 IDLE
12288   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12289               OnGroupStreamStatus(group_id_1, GroupStreamStatus::IDLE))
12290           .Times(1);
12291   state_machine_callbacks_->StatusReportCb(group_id_1, GroupStreamStatus::IDLE);
12292 
12293   // Group 2 IDLE
12294   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12295               OnGroupStreamStatus(group_id_2, GroupStreamStatus::IDLE))
12296           .Times(1);
12297   state_machine_callbacks_->StatusReportCb(group_id_2, GroupStreamStatus::IDLE);
12298 
12299   log::info("Group 1 active and start streaming");
12300   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12301               OnGroupStreamStatus(group_id_1, GroupStreamStatus::STREAMING))
12302           .Times(1);
12303   LeAudioClient::Get()->GroupSetActive(group_id_1);
12304   SyncOnMainLoop();
12305   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id_1);
12306   SyncOnMainLoop();
12307   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
12308 
12309   log::info("Group 2 is getting active");
12310   stay_at_releasing_stop_stream = true;
12311   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12312               OnGroupStreamStatus(group_id_1, GroupStreamStatus::IDLE))
12313           .Times(1);
12314   LeAudioClient::Get()->GroupSetActive(group_id_2);
12315   SyncOnMainLoop();
12316 
12317   log::info("Group 2 is starts streaming");
12318   stay_at_qos_config_in_start_stream = true;
12319   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12320               OnGroupStreamStatus(group_id_2, GroupStreamStatus::STREAMING))
12321           .Times(1);
12322   EXPECT_CALL(*mock_le_audio_source_hal_client_, ConfirmStreamingRequest()).Times(1);
12323 
12324   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id_2, AUDIO_SOURCE_INVALID,
12325                  false, false);
12326 
12327   log::info("Group 1 going to IDLE");
12328   do_in_main_thread(base::BindOnce(
12329           [](int group_id,
12330              bluetooth::le_audio::LeAudioGroupStateMachine::Callbacks* state_machine_callbacks) {
12331             state_machine_callbacks->StatusReportCb(group_id, GroupStreamStatus::IDLE);
12332           },
12333           group_id_1, base::Unretained(this->state_machine_callbacks_)));
12334   SyncOnMainLoop();
12335   log::info("Group 2 going to STREAMING");
12336   do_in_main_thread(base::BindOnce(
12337           [](int group_id,
12338              bluetooth::le_audio::LeAudioGroupStateMachine::Callbacks* state_machine_callbacks) {
12339             state_machine_callbacks->StatusReportCb(group_id, GroupStreamStatus::STREAMING);
12340           },
12341           group_id_2, base::Unretained(this->state_machine_callbacks_)));
12342   SyncOnMainLoop();
12343   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
12344   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
12345 }
12346 
TEST_F(UnicastTest,GroupStreamStatusResendAfterRemove)12347 TEST_F(UnicastTest, GroupStreamStatusResendAfterRemove) {
12348   uint8_t group_size = 2;
12349   int group_id = 1;
12350 
12351   // Report working CSIS
12352   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
12353 
12354   ON_CALL(mock_csis_client_module_, GetDesiredSize(_)).WillByDefault(Return(group_size));
12355 
12356   // First earbud
12357   const RawAddress test_address0 = GetTestAddress(0);
12358   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
12359   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
12360                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
12361 
12362   // Second earbud
12363   const RawAddress test_address1 = GetTestAddress(1);
12364   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
12365   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
12366                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
12367                     true /*connect_through_csis*/);
12368 
12369   Mock::VerifyAndClearExpectations(&mock_btif_storage_);
12370 
12371   InSequence s;
12372 
12373   // Activate group, start streaming and immediately stop
12374   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12375               OnGroupStreamStatus(group_id, GroupStreamStatus::STREAMING))
12376           .Times(1);
12377   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12378               OnGroupStreamStatus(group_id, GroupStreamStatus::IDLE))
12379           .Times(1);
12380   LeAudioClient::Get()->GroupSetActive(group_id);
12381   SyncOnMainLoop();
12382   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::STREAMING);
12383   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
12384 
12385   // No resend
12386   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12387               OnGroupStreamStatus(group_id, GroupStreamStatus::IDLE))
12388           .Times(0);
12389   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::IDLE);
12390 
12391   // No resend after removing only one device
12392   /*
12393    * StopStream will put calls on main_loop so to keep the correct order
12394    * of operations and to avoid races we put the test command on main_loop as
12395    * well.
12396    */
12397   do_in_main_thread(base::BindOnce(
12398           [](LeAudioClient* client, const RawAddress& test_address0) {
12399             client->RemoveDevice(test_address0);
12400           },
12401           LeAudioClient::Get(), test_address0));
12402   SyncOnMainLoop();
12403   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12404               OnGroupStreamStatus(group_id, GroupStreamStatus::IDLE))
12405           .Times(0);
12406   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::IDLE);
12407   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
12408 
12409   // Resend after removing last device
12410   /*
12411    * StopStream will put calls on main_loop so to keep the correct order
12412    * of operations and to avoid races we put the test command on main_loop as
12413    * well.
12414    */
12415   do_in_main_thread(base::BindOnce(
12416           [](LeAudioClient* client, const RawAddress& test_address1) {
12417             client->RemoveDevice(test_address1);
12418           },
12419           LeAudioClient::Get(), test_address1));
12420   SyncOnMainLoop();
12421   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12422               OnGroupStreamStatus(group_id, GroupStreamStatus::IDLE))
12423           .Times(1);
12424   state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::IDLE);
12425   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
12426 }
12427 
TEST_F(UnicastTestHandoverMode,SetSinkMonitorModeWhileUnicastIsActive)12428 TEST_F(UnicastTestHandoverMode, SetSinkMonitorModeWhileUnicastIsActive) {
12429   uint8_t group_size = 2;
12430   int group_id = 2;
12431 
12432   // Report working CSIS
12433   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
12434 
12435   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
12436           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
12437 
12438   // First earbud
12439   const RawAddress test_address0 = GetTestAddress(0);
12440   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
12441   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
12442                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
12443 
12444   // Second earbud
12445   const RawAddress test_address1 = GetTestAddress(1);
12446   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
12447   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
12448                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
12449                     true /*connect_through_csis*/);
12450 
12451   // Start streaming
12452   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
12453   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
12454   LeAudioClient::Get()->GroupSetActive(group_id);
12455   SyncOnMainLoop();
12456 
12457   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
12458 
12459   StartStreaming(AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_CONTENT_TYPE_SPEECH, group_id);
12460 
12461   SyncOnMainLoop();
12462   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
12463   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
12464 
12465   // Verify Data transfer on two peer sinks and one source
12466   uint8_t cis_count_out = 2;
12467   uint8_t cis_count_in = 2;
12468   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 40);
12469 
12470   // Imitate activation of monitor mode
12471   do_in_main_thread(base::BindOnce(
12472           &LeAudioClient::SetUnicastMonitorMode, base::Unretained(LeAudioClient::Get()),
12473           bluetooth::le_audio::types::kLeAudioDirectionSink, true /* enable */));
12474 
12475   ASSERT_NE(0lu, streaming_groups.count(group_id));
12476   auto group = streaming_groups.at(group_id);
12477 
12478   // Stop streaming and expect Service to be informed about straming suspension
12479   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12480               OnUnicastMonitorModeStatus(bluetooth::le_audio::types::kLeAudioDirectionSink,
12481                                          UnicastMonitorModeStatus::STREAMING_SUSPENDED))
12482           .Times(1);
12483 
12484   // Stop
12485   StopStreaming(group_id, true);
12486 
12487   if (com::android::bluetooth::flags::leaudio_use_audio_recording_listener()) {
12488     // simulate suspend timeout passed, alarm executing
12489     fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
12490     SyncOnMainLoop();
12491   } else {
12492     // Check if cache configuration is still present
12493     ASSERT_TRUE(group->GetCachedConfiguration(types::LeAudioContextType::CONVERSATIONAL)
12494                         ->confs.get(le_audio::types::kLeAudioDirectionSink)
12495                         .size());
12496     ASSERT_TRUE(group->GetCachedConfiguration(types::LeAudioContextType::CONVERSATIONAL)
12497                         ->confs.get(le_audio::types::kLeAudioDirectionSource)
12498                         .size());
12499 
12500     // Release, Sink HAL client should remain in monitor mode
12501     EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop()).Times(1);
12502     EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(1);
12503     EXPECT_CALL(*mock_le_audio_sink_hal_client_, Stop()).Times(0);
12504     EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(0);
12505     LeAudioClient::Get()->GroupSetActive(bluetooth::groups::kGroupUnknown);
12506     SyncOnMainLoop();
12507 
12508     Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
12509     Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
12510     Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
12511 
12512     // Re-initialize mock for destroyed hal client
12513     RegisterSourceHalClientMock();
12514 
12515     // Setting group inactive, shall not change cached configuration
12516     ASSERT_TRUE(group->GetCachedConfiguration(types::LeAudioContextType::CONVERSATIONAL)
12517                         ->confs.get(le_audio::types::kLeAudioDirectionSink)
12518                         .size());
12519     ASSERT_TRUE(group->GetCachedConfiguration(types::LeAudioContextType::CONVERSATIONAL)
12520                         ->confs.get(le_audio::types::kLeAudioDirectionSource)
12521                         .size());
12522 
12523     EXPECT_CALL(mock_audio_hal_client_callbacks_,
12524                 OnUnicastMonitorModeStatus(bluetooth::le_audio::types::kLeAudioDirectionSink,
12525                                            UnicastMonitorModeStatus::STREAMING_REQUESTED))
12526             .Times(1);
12527 
12528     // Start streaming to trigger next group going to IDLE state
12529     LocalAudioSinkResume();
12530 
12531     EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
12532     EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
12533     LeAudioClient::Get()->GroupSetActive(group_id);
12534     Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
12535     SyncOnMainLoop();
12536 
12537     Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
12538 
12539     StartStreaming(AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_CONTENT_TYPE_SPEECH, group_id);
12540     SyncOnMainLoop();
12541     Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
12542 
12543     // Stop streaming and expect Service to be informed about straming suspension
12544     EXPECT_CALL(mock_audio_hal_client_callbacks_,
12545                 OnUnicastMonitorModeStatus(bluetooth::le_audio::types::kLeAudioDirectionSink,
12546                                            UnicastMonitorModeStatus::STREAMING_SUSPENDED))
12547             .Times(1);
12548 
12549     // Stop
12550     StopStreaming(group_id, true);
12551 
12552     // Release, Sink HAL client should remain in monitor mode
12553     EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop()).Times(1);
12554     EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(1);
12555     EXPECT_CALL(*mock_le_audio_sink_hal_client_, Stop()).Times(0);
12556     EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(0);
12557     LeAudioClient::Get()->GroupSetActive(bluetooth::groups::kGroupUnknown);
12558     SyncOnMainLoop();
12559 
12560     Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
12561     Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
12562     Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
12563 
12564     // De-activate monitoring mode
12565     EXPECT_CALL(*mock_le_audio_sink_hal_client_, Stop()).Times(1);
12566     EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(1);
12567     do_in_main_thread(base::BindOnce(
12568             &LeAudioClient::SetUnicastMonitorMode, base::Unretained(LeAudioClient::Get()),
12569             bluetooth::le_audio::types::kLeAudioDirectionSink, false /* enable */));
12570     SyncOnMainLoop();
12571     Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
12572   }
12573 }
12574 
TEST_F(UnicastTestHandoverMode,SetSinkMonitorModeWhileUnicastIsInactive)12575 TEST_F(UnicastTestHandoverMode, SetSinkMonitorModeWhileUnicastIsInactive) {
12576   uint8_t group_size = 2;
12577   int group_id = 2;
12578 
12579   // Imitate activation of monitor mode
12580   do_in_main_thread(base::BindOnce(
12581           &LeAudioClient::SetUnicastMonitorMode, base::Unretained(LeAudioClient::Get()),
12582           bluetooth::le_audio::types::kLeAudioDirectionSink, true /* enable */));
12583 
12584   // Report working CSIS
12585   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
12586 
12587   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
12588           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
12589 
12590   // First earbud
12591   const RawAddress test_address0 = GetTestAddress(0);
12592   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
12593   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
12594                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
12595 
12596   // Second earbud
12597   const RawAddress test_address1 = GetTestAddress(1);
12598   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
12599   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
12600                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
12601                     true /*connect_through_csis*/);
12602 
12603   // Start streaming
12604   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
12605   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
12606   LeAudioClient::Get()->GroupSetActive(group_id);
12607   SyncOnMainLoop();
12608 
12609   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
12610 
12611   // Expect no streaming request on stream resume when group is already active
12612   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12613               OnUnicastMonitorModeStatus(bluetooth::le_audio::types::kLeAudioDirectionSink,
12614                                          UnicastMonitorModeStatus::STREAMING_REQUESTED))
12615           .Times(0);
12616 
12617   StartStreaming(AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_CONTENT_TYPE_SPEECH, group_id);
12618 
12619   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
12620   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
12621   SyncOnMainLoop();
12622 
12623   // Verify Data transfer on two peer sinks and one source
12624   uint8_t cis_count_out = 2;
12625   uint8_t cis_count_in = 2;
12626   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 40);
12627 
12628   ASSERT_NE(0lu, streaming_groups.count(group_id));
12629   auto group = streaming_groups.at(group_id);
12630 
12631   // Stop streaming and expect Service to be informed about straming suspension
12632   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12633               OnUnicastMonitorModeStatus(bluetooth::le_audio::types::kLeAudioDirectionSink,
12634                                          UnicastMonitorModeStatus::STREAMING_SUSPENDED))
12635           .Times(1);
12636 
12637   // Stop
12638   StopStreaming(group_id, true);
12639 
12640   if (com::android::bluetooth::flags::leaudio_use_audio_recording_listener()) {
12641     // simulate suspend timeout passed, alarm executing
12642     fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
12643     SyncOnMainLoop();
12644   } else {
12645     // Check if cache configuration is still present
12646     ASSERT_TRUE(group->GetCachedConfiguration(types::LeAudioContextType::CONVERSATIONAL)
12647                         ->confs.get(le_audio::types::kLeAudioDirectionSink)
12648                         .size());
12649     ASSERT_TRUE(group->GetCachedConfiguration(types::LeAudioContextType::CONVERSATIONAL)
12650                         ->confs.get(le_audio::types::kLeAudioDirectionSource)
12651                         .size());
12652 
12653     // Release, Sink HAL client should remain in monitor mode
12654     EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop()).Times(1);
12655     EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(1);
12656     EXPECT_CALL(*mock_le_audio_sink_hal_client_, Stop()).Times(0);
12657     EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(0);
12658     LeAudioClient::Get()->GroupSetActive(bluetooth::groups::kGroupUnknown);
12659     SyncOnMainLoop();
12660 
12661     Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
12662     Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
12663     Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
12664 
12665     // Setting group inactive, shall not change cached configuration
12666     ASSERT_TRUE(group->GetCachedConfiguration(types::LeAudioContextType::CONVERSATIONAL)
12667                         ->confs.get(le_audio::types::kLeAudioDirectionSink)
12668                         .size());
12669     ASSERT_TRUE(group->GetCachedConfiguration(types::LeAudioContextType::CONVERSATIONAL)
12670                         ->confs.get(le_audio::types::kLeAudioDirectionSource)
12671                         .size());
12672   }
12673 }
12674 
TEST_F(UnicastTestHandoverMode,ClearSinkMonitorModeWhileUnicastIsActive)12675 TEST_F(UnicastTestHandoverMode, ClearSinkMonitorModeWhileUnicastIsActive) {
12676   uint8_t group_size = 2;
12677   int group_id = 2;
12678 
12679   // Imitate activation of monitor mode
12680   do_in_main_thread(base::BindOnce(
12681           &LeAudioClient::SetUnicastMonitorMode, base::Unretained(LeAudioClient::Get()),
12682           bluetooth::le_audio::types::kLeAudioDirectionSink, true /* enable */));
12683 
12684   // Report working CSIS
12685   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
12686 
12687   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
12688           .WillByDefault(Invoke([&](int /*group_id*/) { return group_size; }));
12689 
12690   // First earbud
12691   const RawAddress test_address0 = GetTestAddress(0);
12692   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
12693   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
12694                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
12695 
12696   // Second earbud
12697   const RawAddress test_address1 = GetTestAddress(1);
12698   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
12699   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
12700                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
12701                     true /*connect_through_csis*/);
12702 
12703   // Start streaming
12704   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
12705   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
12706   LeAudioClient::Get()->GroupSetActive(group_id);
12707   SyncOnMainLoop();
12708 
12709   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
12710 
12711   // Expect no streaming request on stream resume when group is already active
12712   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12713               OnUnicastMonitorModeStatus(bluetooth::le_audio::types::kLeAudioDirectionSink,
12714                                          UnicastMonitorModeStatus::STREAMING_REQUESTED))
12715           .Times(0);
12716 
12717   StartStreaming(AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_CONTENT_TYPE_SPEECH, group_id);
12718 
12719   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
12720   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
12721   SyncOnMainLoop();
12722 
12723   // Verify Data transfer on two peer sinks and one source
12724   uint8_t cis_count_out = 2;
12725   uint8_t cis_count_in = 2;
12726   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 40);
12727 
12728   ASSERT_NE(0lu, streaming_groups.count(group_id));
12729   auto group = streaming_groups.at(group_id);
12730 
12731   // De-activate monitoring mode
12732   do_in_main_thread(base::BindOnce(
12733           &LeAudioClient::SetUnicastMonitorMode, base::Unretained(LeAudioClient::Get()),
12734           bluetooth::le_audio::types::kLeAudioDirectionSink, false /* enable */));
12735 
12736   // Stop
12737   StopStreaming(group_id, true);
12738   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
12739 
12740   // Check if cache configuration is still present
12741   ASSERT_TRUE(group->GetCachedConfiguration(types::LeAudioContextType::CONVERSATIONAL)
12742                       ->confs.get(le_audio::types::kLeAudioDirectionSink)
12743                       .size());
12744   ASSERT_TRUE(group->GetCachedConfiguration(types::LeAudioContextType::CONVERSATIONAL)
12745                       ->confs.get(le_audio::types::kLeAudioDirectionSource)
12746                       .size());
12747 
12748   // Release of sink and source hals due to de-activating monitor mode
12749   EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop()).Times(1);
12750   EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(1);
12751   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Stop()).Times(1);
12752   EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(1);
12753   LeAudioClient::Get()->GroupSetActive(bluetooth::groups::kGroupUnknown);
12754   SyncOnMainLoop();
12755 
12756   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
12757   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
12758 
12759   // Setting group inactive, shall not change cached configuration
12760   ASSERT_TRUE(group->GetCachedConfiguration(types::LeAudioContextType::CONVERSATIONAL)
12761                       ->confs.get(le_audio::types::kLeAudioDirectionSink)
12762                       .size());
12763   ASSERT_TRUE(group->GetCachedConfiguration(types::LeAudioContextType::CONVERSATIONAL)
12764                       ->confs.get(le_audio::types::kLeAudioDirectionSource)
12765                       .size());
12766 }
12767 
TEST_F(UnicastTestHandoverMode,SetAndClearSinkMonitorModeWhileUnicastIsInactive)12768 TEST_F(UnicastTestHandoverMode, SetAndClearSinkMonitorModeWhileUnicastIsInactive) {
12769   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(0);
12770   EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop()).Times(0);
12771   EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(0);
12772   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(0);
12773   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Stop()).Times(0);
12774   EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(0);
12775 
12776   // Imitate activation of monitor mode
12777   do_in_main_thread(base::BindOnce(
12778           &LeAudioClient::SetUnicastMonitorMode, base::Unretained(LeAudioClient::Get()),
12779           bluetooth::le_audio::types::kLeAudioDirectionSink, true /* enable */));
12780   do_in_main_thread(base::BindOnce(
12781           &LeAudioClient::SetUnicastMonitorMode, base::Unretained(LeAudioClient::Get()),
12782           bluetooth::le_audio::types::kLeAudioDirectionSink, false /* enable */));
12783 
12784   SyncOnMainLoop();
12785 
12786   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
12787   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
12788 }
12789 
TEST_F(UnicastTestHandoverMode,SetSourceMonitorModeWhileUnicastIsInactive)12790 TEST_F(UnicastTestHandoverMode, SetSourceMonitorModeWhileUnicastIsInactive) {
12791   /* Enabling monitor mode for source while group is not active should result in
12792    * sending STREAMING_SUSPENDED notification.
12793    */
12794   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12795               OnUnicastMonitorModeStatus(bluetooth::le_audio::types::kLeAudioDirectionSource,
12796                                          UnicastMonitorModeStatus::STREAMING_SUSPENDED))
12797           .Times(1);
12798 
12799   // Imitate activation of monitor mode
12800   do_in_main_thread(base::BindOnce(
12801           &LeAudioClient::SetUnicastMonitorMode, base::Unretained(LeAudioClient::Get()),
12802           bluetooth::le_audio::types::kLeAudioDirectionSource, true /* enable */));
12803   SyncOnMainLoop();
12804   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
12805 }
12806 
TEST_F(UnicastTestHandoverMode,SetTwiceSourceMonitorModeWhileUnicastIsInactive)12807 TEST_F(UnicastTestHandoverMode, SetTwiceSourceMonitorModeWhileUnicastIsInactive) {
12808   /* Enabling monitor mode for source while group is not active should result in
12809    * sending STREAMING_SUSPENDED notification.
12810    */
12811   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12812               OnUnicastMonitorModeStatus(bluetooth::le_audio::types::kLeAudioDirectionSource,
12813                                          UnicastMonitorModeStatus::STREAMING_SUSPENDED))
12814           .Times(1);
12815 
12816   // Imitate activation of monitor mode
12817   do_in_main_thread(base::BindOnce(
12818           &LeAudioClient::SetUnicastMonitorMode, base::Unretained(LeAudioClient::Get()),
12819           bluetooth::le_audio::types::kLeAudioDirectionSource, true /* enable */));
12820   // Imitate second activation of monitor mode - should not be notified
12821   do_in_main_thread(base::BindOnce(
12822           &LeAudioClient::SetUnicastMonitorMode, base::Unretained(LeAudioClient::Get()),
12823           bluetooth::le_audio::types::kLeAudioDirectionSource, true /* enable */));
12824   SyncOnMainLoop();
12825   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
12826 }
12827 
TEST_F(UnicastTestHandoverMode,SetSourceMonitorModeWhileUnicastIsNotStreaming)12828 TEST_F(UnicastTestHandoverMode, SetSourceMonitorModeWhileUnicastIsNotStreaming) {
12829   int group_id = 2;
12830 
12831   LeAudioClient::Get()->GroupSetActive(group_id);
12832 
12833   /* Enabling monitor mode for source while group is not active should result in
12834    * sending STREAMING_SUSPENDED notification.
12835    */
12836   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12837               OnUnicastMonitorModeStatus(bluetooth::le_audio::types::kLeAudioDirectionSource,
12838                                          UnicastMonitorModeStatus::STREAMING_SUSPENDED))
12839           .Times(1);
12840 
12841   // Imitate activation of monitor mode
12842   do_in_main_thread(base::BindOnce(
12843           &LeAudioClient::SetUnicastMonitorMode, base::Unretained(LeAudioClient::Get()),
12844           bluetooth::le_audio::types::kLeAudioDirectionSource, true /* enable */));
12845   SyncOnMainLoop();
12846   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
12847 }
12848 
TEST_F(UnicastTestHandoverMode,SetSourceMonitorModeWhileUnicastIsActive)12849 TEST_F(UnicastTestHandoverMode, SetSourceMonitorModeWhileUnicastIsActive) {
12850   uint8_t group_size = 2;
12851   int group_id = 2;
12852 
12853   // Report working CSIS
12854   ON_CALL(mock_csis_client_module_, IsCsisClientRunning()).WillByDefault(Return(true));
12855 
12856   // First earbud
12857   const RawAddress test_address0 = GetTestAddress(0);
12858   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)).Times(1);
12859   ConnectCsisDevice(test_address0, 1 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontLeft,
12860                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size, group_id, 1 /* rank*/);
12861 
12862   // Second earbud
12863   const RawAddress test_address1 = GetTestAddress(1);
12864   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)).Times(1);
12865   ConnectCsisDevice(test_address1, 2 /*conn_id*/, codec_spec_conf::kLeAudioLocationFrontRight,
12866                     codec_spec_conf::kLeAudioLocationFrontRight, group_size, group_id, 2 /* rank*/,
12867                     true /*connect_through_csis*/);
12868 
12869   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
12870           .WillByDefault(Invoke([&](int /*group_id*/) { return 2; }));
12871 
12872   // Start streaming
12873   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
12874   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
12875   LeAudioClient::Get()->GroupSetActive(group_id);
12876   SyncOnMainLoop();
12877 
12878   StartStreaming(AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_CONTENT_TYPE_SPEECH, group_id);
12879 
12880   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
12881   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
12882   SyncOnMainLoop();
12883 
12884   // Verify Data transfer on two peer sinks and one source
12885   uint8_t cis_count_out = 2;
12886   uint8_t cis_count_in = 2;
12887   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 40);
12888 
12889   /* Enabling monitor mode for source while stream is active should result in
12890    * sending STREAMING notification.
12891    */
12892   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12893               OnUnicastMonitorModeStatus(bluetooth::le_audio::types::kLeAudioDirectionSource,
12894                                          UnicastMonitorModeStatus::STREAMING))
12895           .Times(1);
12896 
12897   // Imitate activation of monitor mode
12898   do_in_main_thread(base::BindOnce(
12899           &LeAudioClient::SetUnicastMonitorMode, base::Unretained(LeAudioClient::Get()),
12900           bluetooth::le_audio::types::kLeAudioDirectionSource, true /* enable */));
12901   SyncOnMainLoop();
12902   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
12903 
12904   ASSERT_NE(0lu, streaming_groups.count(group_id));
12905   auto group = streaming_groups.at(group_id);
12906 
12907   // Stop streaming and expect Service to be informed about straming suspension
12908   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12909               OnUnicastMonitorModeStatus(bluetooth::le_audio::types::kLeAudioDirectionSource,
12910                                          UnicastMonitorModeStatus::STREAMING_SUSPENDED))
12911           .Times(1);
12912 
12913   // Stop
12914   StopStreaming(group_id, true);
12915 
12916   // Check if cache configuration is still present
12917   ASSERT_TRUE(group->GetCachedConfiguration(types::LeAudioContextType::CONVERSATIONAL)
12918                       ->confs.get(le_audio::types::kLeAudioDirectionSink)
12919                       .size());
12920   ASSERT_TRUE(group->GetCachedConfiguration(types::LeAudioContextType::CONVERSATIONAL)
12921                       ->confs.get(le_audio::types::kLeAudioDirectionSource)
12922                       .size());
12923 
12924   // Both Sink and Source HAL clients should be stopped
12925   EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop()).Times(1);
12926   EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(1);
12927   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Stop()).Times(1);
12928   EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(1);
12929   LeAudioClient::Get()->GroupSetActive(bluetooth::groups::kGroupUnknown);
12930   SyncOnMainLoop();
12931 
12932   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
12933   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
12934   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
12935 
12936   // Re-initialize mock for destroyed hal client
12937   RegisterSourceHalClientMock();
12938   RegisterSinkHalClientMock();
12939 
12940   // Setting group inactive, shall not change cached configuration
12941   ASSERT_TRUE(group->GetCachedConfiguration(types::LeAudioContextType::CONVERSATIONAL)
12942                       ->confs.get(le_audio::types::kLeAudioDirectionSink)
12943                       .size());
12944   ASSERT_TRUE(group->GetCachedConfiguration(types::LeAudioContextType::CONVERSATIONAL)
12945                       ->confs.get(le_audio::types::kLeAudioDirectionSource)
12946                       .size());
12947 
12948   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12949               OnUnicastMonitorModeStatus(bluetooth::le_audio::types::kLeAudioDirectionSource,
12950                                          UnicastMonitorModeStatus::STREAMING_REQUESTED))
12951           .Times(1);
12952 
12953   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
12954   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
12955   LeAudioClient::Get()->GroupSetActive(group_id);
12956 
12957   // Start streaming to trigger next group going to IDLE state
12958   StartStreaming(AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_CONTENT_TYPE_SPEECH, group_id);
12959   SyncOnMainLoop();
12960 
12961   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
12962   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
12963   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
12964 
12965   // Stop streaming and expect Service to be informed about straming suspension
12966   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12967               OnUnicastMonitorModeStatus(bluetooth::le_audio::types::kLeAudioDirectionSource,
12968                                          UnicastMonitorModeStatus::STREAMING_SUSPENDED))
12969           .Times(1);
12970 
12971   // Stop
12972   StopStreaming(group_id, true);
12973 
12974   // Both Sink and Source HAL clients should be stopped
12975   EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop()).Times(1);
12976   EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(1);
12977   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Stop()).Times(1);
12978   EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(1);
12979   LeAudioClient::Get()->GroupSetActive(bluetooth::groups::kGroupUnknown);
12980   SyncOnMainLoop();
12981 
12982   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
12983   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
12984   Mock::VerifyAndClearExpectations(mock_le_audio_sink_hal_client_);
12985 
12986   // De-activate monitoring mode
12987   EXPECT_CALL(mock_audio_hal_client_callbacks_,
12988               OnUnicastMonitorModeStatus(bluetooth::le_audio::types::kLeAudioDirectionSource,
12989                                          UnicastMonitorModeStatus::STREAMING_SUSPENDED))
12990           .Times(0);
12991 
12992   do_in_main_thread(base::BindOnce(
12993           &LeAudioClient::SetUnicastMonitorMode, base::Unretained(LeAudioClient::Get()),
12994           bluetooth::le_audio::types::kLeAudioDirectionSink, false /* enable */));
12995 }
12996 
TEST_F(UnicastTestHandoverMode,SetAllowedContextMask)12997 TEST_F(UnicastTestHandoverMode, SetAllowedContextMask) {
12998   const RawAddress test_address0 = GetTestAddress(0);
12999   int group_id = bluetooth::groups::kGroupUnknown;
13000 
13001   available_snk_context_types_ =
13002           (types::LeAudioContextType::RINGTONE | types::LeAudioContextType::CONVERSATIONAL |
13003            types::LeAudioContextType::UNSPECIFIED | types::LeAudioContextType::MEDIA |
13004            types::LeAudioContextType::SOUNDEFFECTS)
13005                   .value();
13006   available_src_context_types_ = available_snk_context_types_;
13007   supported_snk_context_types_ = types::kLeAudioContextAllTypes.value();
13008   supported_src_context_types_ =
13009           (types::kLeAudioContextAllRemoteSource | types::LeAudioContextType::UNSPECIFIED).value();
13010   /* Don't allow SOUNDEFFECTS context type to be streamed */
13011   int allowed_context_types =
13012           (types::LeAudioContextType::RINGTONE | types::LeAudioContextType::CONVERSATIONAL |
13013            types::LeAudioContextType::UNSPECIFIED | types::LeAudioContextType::MEDIA)
13014                   .value();
13015 
13016   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
13017                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
13018                                 default_channel_cnt, 0x0004, false /*add_csis*/, true /*add_cas*/,
13019                                 true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
13020                                 0 /*rank*/);
13021   EXPECT_CALL(mock_audio_hal_client_callbacks_,
13022               OnConnectionState(ConnectionState::CONNECTED, test_address0))
13023           .Times(1);
13024   EXPECT_CALL(mock_audio_hal_client_callbacks_,
13025               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
13026           .WillOnce(DoAll(SaveArg<1>(&group_id)));
13027 
13028   ConnectLeAudio(test_address0);
13029   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
13030 
13031   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
13032   EXPECT_CALL(mock_state_machine_, StartStream(_, types::LeAudioContextType::SOUNDEFFECTS, _, _))
13033           .Times(0);
13034 
13035   LeAudioClient::Get()->GroupSetActive(group_id);
13036   SyncOnMainLoop();
13037 
13038   /* Set the same allowed context mask for sink and source */
13039   LeAudioClient::Get()->SetGroupAllowedContextMask(group_id, allowed_context_types,
13040                                                    allowed_context_types);
13041 
13042   StartStreaming(AUDIO_USAGE_ASSISTANCE_SONIFICATION, AUDIO_CONTENT_TYPE_UNKNOWN, group_id,
13043                  AUDIO_SOURCE_INVALID, false, false);
13044 
13045   SyncOnMainLoop();
13046   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
13047   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
13048 }
13049 
TEST_F(UnicastTest,NoContextvalidateStreamingRequest)13050 TEST_F(UnicastTest, NoContextvalidateStreamingRequest) {
13051   const RawAddress test_address0 = GetTestAddress(0);
13052   int group_id = bluetooth::groups::kGroupUnknown;
13053 
13054   available_snk_context_types_ =
13055           (types::LeAudioContextType::RINGTONE | types::LeAudioContextType::CONVERSATIONAL |
13056            types::LeAudioContextType::UNSPECIFIED | types::LeAudioContextType::MEDIA)
13057                   .value();
13058   available_src_context_types_ = available_snk_context_types_;
13059   supported_snk_context_types_ = types::kLeAudioContextAllTypes.value();
13060   supported_src_context_types_ =
13061           (types::kLeAudioContextAllRemoteSource | types::LeAudioContextType::UNSPECIFIED).value();
13062 
13063   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
13064                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
13065                                 default_channel_cnt, 0x0004, false /*add_csis*/, true /*add_cas*/,
13066                                 true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
13067                                 0 /*rank*/);
13068   EXPECT_CALL(mock_audio_hal_client_callbacks_,
13069               OnConnectionState(ConnectionState::CONNECTED, test_address0))
13070           .Times(1);
13071   EXPECT_CALL(mock_audio_hal_client_callbacks_,
13072               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
13073           .WillOnce(DoAll(SaveArg<1>(&group_id)));
13074 
13075   ConnectLeAudio(test_address0);
13076   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
13077 
13078   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
13079   types::BidirectionalPair<types::AudioContexts> metadata = {.sink = types::AudioContexts(),
13080                                                              .source = types::AudioContexts()};
13081   EXPECT_CALL(mock_state_machine_,
13082               StartStream(_, types::LeAudioContextType::SOUNDEFFECTS, metadata, _))
13083           .Times(0);
13084 
13085   LeAudioClient::Get()->GroupSetActive(group_id);
13086 
13087   // Imitate activation of monitor mode
13088   do_in_main_thread(base::BindOnce(
13089           &LeAudioClient::SetUnicastMonitorMode, base::Unretained(LeAudioClient::Get()),
13090           bluetooth::le_audio::types::kLeAudioDirectionSource, true /* enable */));
13091   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
13092   SyncOnMainLoop();
13093 
13094   // Stop streaming and expect Service to be informed about streaming suspension
13095   EXPECT_CALL(mock_audio_hal_client_callbacks_,
13096               OnUnicastMonitorModeStatus(
13097                       bluetooth::le_audio::types::kLeAudioDirectionSource,
13098                       UnicastMonitorModeStatus::STREAMING_REQUESTED_NO_CONTEXT_VALIDATE))
13099           .Times(1);
13100 
13101   StartStreaming(AUDIO_USAGE_ASSISTANCE_SONIFICATION, AUDIO_CONTENT_TYPE_UNKNOWN, group_id,
13102                  AUDIO_SOURCE_INVALID, false, false);
13103 
13104   SyncOnMainLoop();
13105   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
13106   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
13107 }
13108 
TEST_F(UnicastTest,CodecFrameBlocks2)13109 TEST_F(UnicastTest, CodecFrameBlocks2) {
13110   auto const max_codec_frames_per_sdu = 2;
13111   uint32_t data_len = 1920;
13112 
13113   // Register a on-the-fly hook for codec interface mock mutation to prepare the
13114   // codec mock for encoding
13115   std::list<MockCodecInterface*> codec_mocks;
13116   MockCodecInterface::RegisterMockInstanceHook([&](MockCodecInterface* mock, bool is_destroyed) {
13117     if (is_destroyed) {
13118       log::debug("Codec Interface Destroyed: {}", std::format_ptr(mock));
13119       codec_mocks.remove(mock);
13120     } else {
13121       log::debug("Codec Interface Created: {}", std::format_ptr(mock));
13122       ON_CALL(*mock, GetNumOfSamplesPerChannel()).WillByDefault(Return(960));
13123       ON_CALL(*mock, GetNumOfBytesPerSample()).WillByDefault(Return(2));  // 16bits samples
13124       ON_CALL(*mock, Encode(_, _, _, _, _))
13125               .WillByDefault(Return(CodecInterface::Status::STATUS_OK));
13126       codec_mocks.push_back(mock);
13127     }
13128   });
13129 
13130   // Add a frame block PAC passing provider
13131   bool is_fb2_passed_as_requirement = false;
13132   ON_CALL(*mock_codec_manager_, GetCodecConfig)
13133           .WillByDefault(Invoke(
13134                   [&](const bluetooth::le_audio::CodecManager::UnicastConfigurationRequirements&
13135                               requirements,
13136                       bluetooth::le_audio::CodecManager::UnicastConfigurationProvider provider) {
13137                     auto filtered = *bluetooth::le_audio::AudioSetConfigurationProvider::Get()
13138                                              ->GetConfigurations(requirements.audio_context_type);
13139                     // Filter out the dual bidir SWB configurations
13140                     if (!bluetooth::le_audio::CodecManager::GetInstance()
13141                                  ->IsDualBiDirSwbSupported()) {
13142                       filtered.erase(
13143                               std::remove_if(filtered.begin(), filtered.end(),
13144                                              [](auto const& el) {
13145                                                if (el->confs.source.empty()) {
13146                                                  return false;
13147                                                }
13148                                                return AudioSetConfigurationProvider::Get()
13149                                                        ->CheckConfigurationIsDualBiDirSwb(*el);
13150                                              }),
13151                               filtered.end());
13152                     }
13153                     auto cfg = provider(requirements, &filtered);
13154                     if (cfg == nullptr) {
13155                       return std::unique_ptr<bluetooth::le_audio::types::AudioSetConfiguration>(
13156                               nullptr);
13157                     }
13158 
13159                     if (requirements.sink_pacs.has_value()) {
13160                       for (auto const& rec : requirements.sink_pacs.value()) {
13161                         auto caps = rec.codec_spec_caps.GetAsCoreCodecCapabilities();
13162                         if (caps.HasSupportedMaxCodecFramesPerSdu()) {
13163                           if (caps.supported_max_codec_frames_per_sdu.value() ==
13164                               max_codec_frames_per_sdu) {
13165                             // Inject the proper Codec Frames Per SDU as the json
13166                             // configs are conservative and will always give us 1
13167                             for (auto& entry : cfg->confs.sink) {
13168                               entry.codec.params.Add(
13169                                       codec_spec_conf::kLeAudioLtvTypeCodecFrameBlocksPerSdu,
13170                                       (uint8_t)max_codec_frames_per_sdu);
13171                             }
13172                             is_fb2_passed_as_requirement = true;
13173                           }
13174                         }
13175                       }
13176                     }
13177                     return cfg;
13178                   }));
13179 
13180   types::BidirectionalPair<stream_parameters> codec_manager_stream_params;
13181   ON_CALL(*mock_codec_manager_, UpdateActiveAudioConfig)
13182           .WillByDefault(
13183                   Invoke([&](const types::BidirectionalPair<stream_parameters>& stream_params,
13184                              std::function<void(const stream_config& config, uint8_t direction)>
13185                              /*updater*/,
13186                              uint8_t /*directions_to_update*/) {
13187                     codec_manager_stream_params = stream_params;
13188                   }));
13189 
13190   const RawAddress test_address0 = GetTestAddress(0);
13191   int group_id = bluetooth::groups::kGroupUnknown;
13192 
13193   SampleDatabaseParameters remote_params{
13194           .conn_id = 1,
13195           .addr = test_address0,
13196           .sink_audio_allocation = codec_spec_conf::kLeAudioLocationStereo,
13197           .source_audio_allocation = codec_spec_conf::kLeAudioLocationStereo,
13198           .sink_channel_cnt = default_channel_cnt,
13199           .source_channel_cnt = default_channel_cnt,
13200           .sample_freq_mask = le_audio::codec_spec_caps::kLeAudioSamplingFreq32000Hz,
13201           .add_csis = false,
13202           .add_cas = true,
13203           .add_pacs = true,
13204           .add_ascs_cnt = 1,
13205           .set_size = 0,
13206           .rank = 0,
13207           .gatt_status = GATT_SUCCESS,
13208           .max_supported_codec_frames_per_sdu = 2,
13209   };
13210   SetSampleDatabaseEarbudsValid(remote_params);
13211 
13212   EXPECT_CALL(mock_audio_hal_client_callbacks_,
13213               OnConnectionState(ConnectionState::CONNECTED, test_address0))
13214           .Times(1);
13215   EXPECT_CALL(mock_audio_hal_client_callbacks_,
13216               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
13217           .WillOnce(DoAll(SaveArg<1>(&group_id)));
13218 
13219   ConnectLeAudio(test_address0);
13220   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
13221 
13222   constexpr int gmcs_ccid = 1;
13223   constexpr int gtbs_ccid = 2;
13224 
13225   // Audio sessions are started only when device gets active
13226   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
13227   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
13228   LeAudioClient::Get()->SetCcidInformation(gmcs_ccid, 4 /* Media */);
13229   LeAudioClient::Get()->SetCcidInformation(gtbs_ccid, 2 /* Phone */);
13230   LeAudioClient::Get()->GroupSetActive(group_id);
13231   SyncOnMainLoop();
13232 
13233   types::BidirectionalPair<std::vector<uint8_t>> ccids = {.sink = {gmcs_ccid}, .source = {}};
13234   EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, ccids)).Times(1);
13235 
13236   stay_at_qos_config_in_start_stream = true;
13237 
13238   UpdateLocalSourceMetadata(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC);
13239   LocalAudioSourceResume(false);
13240 
13241   SyncOnMainLoop();
13242   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
13243   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
13244   ASSERT_TRUE(is_fb2_passed_as_requirement);
13245 
13246   // Verify codec fram blocks per SDU has been applied to the device
13247   ASSERT_NE(0lu, streaming_groups.count(group_id));
13248   uint8_t device_configured_codec_frame_blocks_per_sdu = 0;
13249   auto group = streaming_groups.at(group_id);
13250   for (LeAudioDevice* device = group->GetFirstDevice(); device != nullptr;
13251        device = group->GetNextDevice(device)) {
13252     for (auto& ase : device->ases_) {
13253       if (ase.active) {
13254         auto cfg = ase.codec_config.params.GetAsCoreCodecConfig();
13255         ASSERT_TRUE(cfg.codec_frames_blocks_per_sdu.has_value());
13256         device_configured_codec_frame_blocks_per_sdu = cfg.codec_frames_blocks_per_sdu.value();
13257       }
13258     }
13259   }
13260 
13261   // Verify the configured codec frame blocks per SDU
13262   ASSERT_EQ(device_configured_codec_frame_blocks_per_sdu,
13263             remote_params.max_supported_codec_frames_per_sdu);
13264 
13265   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(0);
13266   do_in_main_thread(base::BindOnce(
13267           [](int group_id,
13268              bluetooth::le_audio::LeAudioGroupStateMachine::Callbacks* state_machine_callbacks) {
13269             state_machine_callbacks->StatusReportCb(group_id, GroupStreamStatus::STREAMING);
13270           },
13271           group_id, base::Unretained(state_machine_callbacks_)));
13272   SyncOnMainLoop();
13273   Mock::VerifyAndClearExpectations(&mock_state_machine_);
13274 
13275   // Verify Data transfer on one audio source cis
13276   constexpr uint8_t cis_count_out = 1;
13277   constexpr uint8_t cis_count_in = 0;
13278   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in,
13279                         data_len * device_configured_codec_frame_blocks_per_sdu);
13280 
13281   ASSERT_NE(codec_mocks.size(), 0ul);
13282 
13283   // Verify that the initially started session was updated with the new params
13284   ASSERT_EQ(codec_manager_stream_params.sink.stream_config.codec_frames_blocks_per_sdu,
13285             max_codec_frames_per_sdu);
13286 }
13287 
TEST_F(UnicastTestHandoverMode,UpdateMetadataToNotAllowedContexts)13288 TEST_F(UnicastTestHandoverMode, UpdateMetadataToNotAllowedContexts) {
13289   com::android::bluetooth::flags::provider_->leaudio_stop_updated_to_not_available_context_stream(
13290           true);
13291   const RawAddress test_address0 = GetTestAddress(0);
13292   int group_id = bluetooth::groups::kGroupUnknown;
13293 
13294   available_snk_context_types_ =
13295           (types::LeAudioContextType::RINGTONE | types::LeAudioContextType::CONVERSATIONAL |
13296            types::LeAudioContextType::UNSPECIFIED | types::LeAudioContextType::MEDIA |
13297            types::LeAudioContextType::SOUNDEFFECTS)
13298                   .value();
13299   available_src_context_types_ = available_snk_context_types_;
13300   supported_snk_context_types_ = types::kLeAudioContextAllTypes.value();
13301   supported_src_context_types_ =
13302           (types::kLeAudioContextAllRemoteSource | types::LeAudioContextType::UNSPECIFIED).value();
13303   /* Don't allow SOUNDEFFECTS context type to be streamed */
13304   int allowed_context_types =
13305           (types::LeAudioContextType::RINGTONE | types::LeAudioContextType::CONVERSATIONAL |
13306            types::LeAudioContextType::UNSPECIFIED | types::LeAudioContextType::MEDIA)
13307                   .value();
13308 
13309   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
13310                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
13311                                 default_channel_cnt, 0x0004, false /*add_csis*/, true /*add_cas*/,
13312                                 true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
13313                                 0 /*rank*/);
13314   EXPECT_CALL(mock_audio_hal_client_callbacks_,
13315               OnConnectionState(ConnectionState::CONNECTED, test_address0))
13316           .Times(1);
13317   EXPECT_CALL(mock_audio_hal_client_callbacks_,
13318               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
13319           .WillOnce(DoAll(SaveArg<1>(&group_id)));
13320 
13321   ConnectLeAudio(test_address0);
13322   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
13323 
13324   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
13325   types::BidirectionalPair<types::AudioContexts> metadata = {.sink = types::AudioContexts(),
13326                                                              .source = types::AudioContexts()};
13327   EXPECT_CALL(mock_state_machine_, StartStream(_, types::LeAudioContextType::MEDIA, _, _)).Times(1);
13328 
13329   LeAudioClient::Get()->GroupSetActive(group_id);
13330   SyncOnMainLoop();
13331 
13332   /* Set the same allowed context mask for sink and source */
13333   LeAudioClient::Get()->SetGroupAllowedContextMask(group_id, allowed_context_types,
13334                                                    allowed_context_types);
13335 
13336   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_UNKNOWN, group_id, AUDIO_SOURCE_INVALID,
13337                  false, false);
13338 
13339   SyncOnMainLoop();
13340   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
13341   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
13342 
13343   /* Expect stream to be stopped when not allowed context would be updated in metadata */
13344   EXPECT_CALL(mock_state_machine_, StopStream(_));
13345 
13346   UpdateLocalSourceMetadata(AUDIO_USAGE_ASSISTANCE_SONIFICATION, AUDIO_CONTENT_TYPE_UNKNOWN, true);
13347 }
13348 
TEST_F(UnicastTestHandoverMode,UpdateMetadataToNotAllowedContextsInCallMode)13349 TEST_F(UnicastTestHandoverMode, UpdateMetadataToNotAllowedContextsInCallMode) {
13350   com::android::bluetooth::flags::provider_->leaudio_stop_updated_to_not_available_context_stream(
13351           true);
13352   const RawAddress test_address0 = GetTestAddress(0);
13353   int group_id = bluetooth::groups::kGroupUnknown;
13354 
13355   available_snk_context_types_ =
13356           (types::LeAudioContextType::RINGTONE | types::LeAudioContextType::CONVERSATIONAL |
13357            types::LeAudioContextType::UNSPECIFIED | types::LeAudioContextType::MEDIA |
13358            types::LeAudioContextType::SOUNDEFFECTS)
13359                   .value();
13360   available_src_context_types_ = available_snk_context_types_;
13361   supported_snk_context_types_ = types::kLeAudioContextAllTypes.value();
13362   supported_src_context_types_ =
13363           (types::kLeAudioContextAllRemoteSource | types::LeAudioContextType::UNSPECIFIED).value();
13364 
13365   /* Don't allow SOUNDEFFECTS context type to be streamed */
13366   int allowed_context_types =
13367           (types::LeAudioContextType::RINGTONE | types::LeAudioContextType::CONVERSATIONAL |
13368            types::LeAudioContextType::UNSPECIFIED | types::LeAudioContextType::MEDIA)
13369                   .value();
13370 
13371   SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
13372                                 codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
13373                                 default_channel_cnt, 0x0004, false /*add_csis*/, true /*add_cas*/,
13374                                 true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
13375                                 0 /*rank*/);
13376   EXPECT_CALL(mock_audio_hal_client_callbacks_,
13377               OnConnectionState(ConnectionState::CONNECTED, test_address0))
13378           .Times(1);
13379   EXPECT_CALL(mock_audio_hal_client_callbacks_,
13380               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
13381           .WillOnce(DoAll(SaveArg<1>(&group_id)));
13382 
13383   ConnectLeAudio(test_address0);
13384   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
13385 
13386   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
13387   types::BidirectionalPair<types::AudioContexts> metadata = {.sink = types::AudioContexts(),
13388                                                              .source = types::AudioContexts()};
13389   EXPECT_CALL(mock_state_machine_, StartStream(_, types::LeAudioContextType::CONVERSATIONAL, _, _))
13390           .Times(1);
13391 
13392   LeAudioClient::Get()->GroupSetActive(group_id);
13393   SyncOnMainLoop();
13394 
13395   /* Set the same allowed context mask for sink and source */
13396   LeAudioClient::Get()->SetGroupAllowedContextMask(group_id, allowed_context_types,
13397                                                    allowed_context_types);
13398 
13399   StartStreaming(AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE, AUDIO_CONTENT_TYPE_SONIFICATION,
13400                  group_id, AUDIO_SOURCE_INVALID, false, false);
13401 
13402   SyncOnMainLoop();
13403   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
13404   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
13405 
13406   /* Expect stream to not be stopped when not allowed context would be updated in metadata and
13407    * inCall mode is set */
13408   LeAudioClient::Get()->SetInCall(true);
13409   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(0);
13410 
13411   /* Expect no reconfiguration while being in call mode */
13412   UpdateLocalSourceMetadata(AUDIO_USAGE_ASSISTANCE_SONIFICATION, AUDIO_CONTENT_TYPE_SONIFICATION,
13413                             false);
13414 
13415   SyncOnMainLoop();
13416 
13417   Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
13418   Mock::VerifyAndClearExpectations(&mock_state_machine_);
13419 
13420   /* Expect stream to be stopped when not allowed context is set and inCall mode is not set */
13421   EXPECT_CALL(mock_state_machine_, StopStream(_));
13422   LeAudioClient::Get()->SetInCall(false);
13423 }
13424 }  // namespace bluetooth::le_audio
13425