• 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 <gmock/gmock.h>
19 #include <gtest/gtest.h>
20 
21 #include <chrono>
22 
23 #include "bta/csis/csis_types.h"
24 #include "bta_gatt_api_mock.h"
25 #include "bta_gatt_queue_mock.h"
26 #include "bta_groups.h"
27 #include "bta_le_audio_api.h"
28 #include "btif_storage_mock.h"
29 #include "btm_api_mock.h"
30 #include "btm_iso_api.h"
31 #include "common/message_loop_thread.h"
32 #include "device/include/controller.h"
33 #include "fake_osi.h"
34 #include "gatt/database_builder.h"
35 #include "hardware/bt_gatt_types.h"
36 #include "internal_include/stack_config.h"
37 #include "le_audio_set_configuration_provider.h"
38 #include "le_audio_types.h"
39 #include "mock_controller.h"
40 #include "mock_csis_client.h"
41 #include "mock_device_groups.h"
42 #include "mock_iso_manager.h"
43 #include "mock_state_machine.h"
44 #include "osi/include/log.h"
45 #include "test/common/mock_functions.h"
46 
47 using testing::_;
48 using testing::AnyNumber;
49 using testing::AtLeast;
50 using testing::AtMost;
51 using testing::DoAll;
52 using testing::Expectation;
53 using testing::Invoke;
54 using testing::Matcher;
55 using testing::Mock;
56 using testing::MockFunction;
57 using testing::NiceMock;
58 using testing::NotNull;
59 using testing::Return;
60 using testing::SaveArg;
61 using testing::SetArgPointee;
62 using testing::Test;
63 using testing::WithArg;
64 
65 using bluetooth::Uuid;
66 
67 using namespace bluetooth::le_audio;
68 
69 using le_audio::LeAudioCodecConfiguration;
70 using le_audio::LeAudioSinkAudioHalClient;
71 using le_audio::LeAudioSourceAudioHalClient;
72 
73 extern struct fake_osi_alarm_set_on_mloop fake_osi_alarm_set_on_mloop_;
74 
75 constexpr int max_num_of_ases = 5;
76 
77 static constexpr char kNotifyUpperLayerAboutGroupBeingInIdleDuringCall[] =
78     "persist.bluetooth.leaudio.notify.idle.during.call";
79 const char* test_flags[] = {
80     "INIT_logging_debug_enabled_for_all=true",
81     "INIT_leaudio_targeted_announcement_reconnection_mode=true",
82     nullptr,
83 };
84 
85 void osi_property_set_bool(const char* key, bool value);
86 
87 // Disables most likely false-positives from base::SplitString()
__asan_default_options()88 extern "C" const char* __asan_default_options() {
89   return "detect_container_overflow=0";
90 }
91 
92 std::atomic<int> num_async_tasks;
93 bluetooth::common::MessageLoopThread message_loop_thread("test message loop");
get_main_thread()94 bluetooth::common::MessageLoopThread* get_main_thread() {
95   return &message_loop_thread;
96 }
do_in_main_thread(const base::Location & from_here,base::OnceClosure task)97 bt_status_t do_in_main_thread(const base::Location& from_here,
98                               base::OnceClosure task) {
99   // Wrap the task with task counter so we could later know if there are
100   // any callbacks scheduled and we should wait before performing some actions
101   if (!message_loop_thread.DoInThread(
102           from_here,
103           base::BindOnce(
104               [](base::OnceClosure task, std::atomic<int>& num_async_tasks) {
105                 std::move(task).Run();
106                 num_async_tasks--;
107               },
108               std::move(task), std::ref(num_async_tasks)))) {
109     LOG(ERROR) << __func__ << ": failed from " << from_here.ToString();
110     return BT_STATUS_FAIL;
111   }
112   num_async_tasks++;
113   return BT_STATUS_SUCCESS;
114 }
115 
do_in_main_thread_delayed(const base::Location & from_here,base::OnceClosure task,const base::TimeDelta & delay)116 bt_status_t do_in_main_thread_delayed(const base::Location& from_here,
117                                       base::OnceClosure task,
118                                       const base::TimeDelta& delay) {
119   /* For testing purpose it is ok to just skip delay */
120   return do_in_main_thread(from_here, std::move(task));
121 }
122 
123 static base::MessageLoop* message_loop_;
get_main_message_loop()124 base::MessageLoop* get_main_message_loop() { return message_loop_; }
125 
init_message_loop_thread()126 static void init_message_loop_thread() {
127   num_async_tasks = 0;
128   message_loop_thread.StartUp();
129   if (!message_loop_thread.IsRunning()) {
130     FAIL() << "unable to create message loop thread.";
131   }
132 
133   if (!message_loop_thread.EnableRealTimeScheduling())
134     LOG(ERROR) << "Unable to set real time scheduling";
135 
136   message_loop_ = message_loop_thread.message_loop();
137   if (message_loop_ == nullptr) FAIL() << "unable to get message loop.";
138 }
139 
cleanup_message_loop_thread()140 static void cleanup_message_loop_thread() {
141   message_loop_ = nullptr;
142   message_loop_thread.ShutDown();
143 }
144 
invoke_switch_codec_cb(bool is_low_latency_buffer_size)145 void invoke_switch_codec_cb(bool is_low_latency_buffer_size) {}
invoke_switch_buffer_size_cb(bool is_low_latency_buffer_size)146 void invoke_switch_buffer_size_cb(bool is_low_latency_buffer_size) {}
147 
148 const std::string kSmpOptions("mock smp options");
get_trace_config_enabled(void)149 bool get_trace_config_enabled(void) { return false; }
get_pts_avrcp_test(void)150 bool get_pts_avrcp_test(void) { return false; }
get_pts_secure_only_mode(void)151 bool get_pts_secure_only_mode(void) { return false; }
get_pts_conn_updates_disabled(void)152 bool get_pts_conn_updates_disabled(void) { return false; }
get_pts_crosskey_sdp_disable(void)153 bool get_pts_crosskey_sdp_disable(void) { return false; }
get_pts_smp_options(void)154 const std::string* get_pts_smp_options(void) { return &kSmpOptions; }
get_pts_smp_failure_case(void)155 int get_pts_smp_failure_case(void) { return 123; }
get_pts_force_eatt_for_notifications(void)156 bool get_pts_force_eatt_for_notifications(void) { return false; }
get_pts_connect_eatt_unconditionally(void)157 bool get_pts_connect_eatt_unconditionally(void) { return false; }
get_pts_connect_eatt_before_encryption(void)158 bool get_pts_connect_eatt_before_encryption(void) { return false; }
get_pts_unencrypt_broadcast(void)159 bool get_pts_unencrypt_broadcast(void) { return false; }
get_pts_eatt_peripheral_collision_support(void)160 bool get_pts_eatt_peripheral_collision_support(void) { return false; }
get_pts_force_le_audio_multiple_contexts_metadata(void)161 bool get_pts_force_le_audio_multiple_contexts_metadata(void) { return false; }
get_pts_le_audio_disable_ases_before_stopping(void)162 bool get_pts_le_audio_disable_ases_before_stopping(void) { return false; }
get_all(void)163 config_t* get_all(void) { return nullptr; }
164 
165 stack_config_t mock_stack_config{
166     .get_trace_config_enabled = get_trace_config_enabled,
167     .get_pts_avrcp_test = get_pts_avrcp_test,
168     .get_pts_secure_only_mode = get_pts_secure_only_mode,
169     .get_pts_conn_updates_disabled = get_pts_conn_updates_disabled,
170     .get_pts_crosskey_sdp_disable = get_pts_crosskey_sdp_disable,
171     .get_pts_smp_options = get_pts_smp_options,
172     .get_pts_smp_failure_case = get_pts_smp_failure_case,
173     .get_pts_force_eatt_for_notifications =
174         get_pts_force_eatt_for_notifications,
175     .get_pts_connect_eatt_unconditionally =
176         get_pts_connect_eatt_unconditionally,
177     .get_pts_connect_eatt_before_encryption =
178         get_pts_connect_eatt_before_encryption,
179     .get_pts_unencrypt_broadcast = get_pts_unencrypt_broadcast,
180     .get_pts_eatt_peripheral_collision_support =
181         get_pts_eatt_peripheral_collision_support,
182     .get_pts_force_le_audio_multiple_contexts_metadata =
183         get_pts_force_le_audio_multiple_contexts_metadata,
184     .get_pts_le_audio_disable_ases_before_stopping =
185         get_pts_le_audio_disable_ases_before_stopping,
186     .get_all = get_all,
187 };
stack_config_get_interface(void)188 const stack_config_t* stack_config_get_interface(void) {
189   return &mock_stack_config;
190 }
191 
192 namespace le_audio {
193 class MockLeAudioSourceHalClient;
194 MockLeAudioSourceHalClient* mock_le_audio_source_hal_client_;
195 std::unique_ptr<LeAudioSourceAudioHalClient>
196     owned_mock_le_audio_source_hal_client_;
197 bool is_audio_unicast_source_acquired;
198 
199 std::unique_ptr<LeAudioSourceAudioHalClient>
AcquireUnicast()200 LeAudioSourceAudioHalClient::AcquireUnicast() {
201   if (is_audio_unicast_source_acquired) return nullptr;
202   is_audio_unicast_source_acquired = true;
203   return std::move(owned_mock_le_audio_source_hal_client_);
204 }
205 
DebugDump(int fd)206 void LeAudioSourceAudioHalClient::DebugDump(int fd) {}
207 
208 class MockLeAudioSinkHalClient;
209 MockLeAudioSinkHalClient* mock_le_audio_sink_hal_client_;
210 std::unique_ptr<LeAudioSinkAudioHalClient> owned_mock_le_audio_sink_hal_client_;
211 bool is_audio_unicast_sink_acquired;
212 
213 std::unique_ptr<LeAudioSinkAudioHalClient>
AcquireUnicast()214 LeAudioSinkAudioHalClient::AcquireUnicast() {
215   if (is_audio_unicast_sink_acquired) return nullptr;
216   is_audio_unicast_sink_acquired = true;
217   return std::move(owned_mock_le_audio_sink_hal_client_);
218 }
219 
DebugDump(int fd)220 void LeAudioSinkAudioHalClient::DebugDump(int fd) {}
221 
222 class MockAudioHalClientCallbacks
223     : public bluetooth::le_audio::LeAudioClientCallbacks {
224  public:
225   MOCK_METHOD((void), OnInitialized, (), (override));
226   MOCK_METHOD((void), OnConnectionState,
227               (ConnectionState state, const RawAddress& address), (override));
228   MOCK_METHOD((void), OnGroupStatus, (int group_id, GroupStatus group_status),
229               (override));
230   MOCK_METHOD((void), OnGroupNodeStatus,
231               (const RawAddress& bd_addr, int group_id,
232                GroupNodeStatus node_status),
233               (override));
234   MOCK_METHOD((void), OnAudioConf,
235               (uint8_t direction, int group_id, uint32_t snk_audio_location,
236                uint32_t src_audio_location, uint16_t avail_cont),
237               (override));
238   MOCK_METHOD((void), OnSinkAudioLocationAvailable,
239               (const RawAddress& bd_addr, uint32_t snk_audio_location),
240               (override));
241   MOCK_METHOD(
242       (void), OnAudioLocalCodecCapabilities,
243       (std::vector<btle_audio_codec_config_t> local_input_capa_codec_conf,
244        std::vector<btle_audio_codec_config_t> local_output_capa_codec_conf),
245       (override));
246   MOCK_METHOD(
247       (void), OnAudioGroupCodecConf,
248       (int group_id, btle_audio_codec_config_t input_codec_conf,
249        btle_audio_codec_config_t output_codec_conf,
250        std::vector<btle_audio_codec_config_t> input_selectable_codec_conf,
251        std::vector<btle_audio_codec_config_t> output_selectable_codec_conf),
252       (override));
253 };
254 
255 class MockLeAudioSinkHalClient : public LeAudioSinkAudioHalClient {
256  public:
257   MockLeAudioSinkHalClient() = default;
258   MOCK_METHOD((bool), Start,
259               (const LeAudioCodecConfiguration& codecConfiguration,
260                LeAudioSinkAudioHalClient::Callbacks* audioReceiver),
261               (override));
262   MOCK_METHOD((void), Stop, (), (override));
263   MOCK_METHOD((size_t), SendData, (uint8_t * data, uint16_t size), (override));
264   MOCK_METHOD((void), ConfirmStreamingRequest, (), (override));
265   MOCK_METHOD((void), CancelStreamingRequest, (), (override));
266   MOCK_METHOD((void), UpdateRemoteDelay, (uint16_t delay), (override));
267   MOCK_METHOD((void), UpdateAudioConfigToHal,
268               (const ::le_audio::offload_config&), (override));
269   MOCK_METHOD((void), SuspendedForReconfiguration, (), (override));
270   MOCK_METHOD((void), ReconfigurationComplete, (), (override));
271 
272   MOCK_METHOD((void), OnDestroyed, ());
~MockLeAudioSinkHalClient()273   virtual ~MockLeAudioSinkHalClient() override { OnDestroyed(); }
274 };
275 
276 class MockLeAudioSourceHalClient : public LeAudioSourceAudioHalClient {
277  public:
278   MockLeAudioSourceHalClient() = default;
279   MOCK_METHOD((bool), Start,
280               (const LeAudioCodecConfiguration& codecConfiguration,
281                LeAudioSourceAudioHalClient::Callbacks* audioReceiver),
282               (override));
283   MOCK_METHOD((void), Stop, (), (override));
284   MOCK_METHOD((void), ConfirmStreamingRequest, (), (override));
285   MOCK_METHOD((void), CancelStreamingRequest, (), (override));
286   MOCK_METHOD((void), UpdateRemoteDelay, (uint16_t delay), (override));
287   MOCK_METHOD((void), UpdateAudioConfigToHal,
288               (const ::le_audio::offload_config&), (override));
289   MOCK_METHOD((void), UpdateBroadcastAudioConfigToHal,
290               (const ::le_audio::broadcast_offload_config&), (override));
291   MOCK_METHOD((void), SuspendedForReconfiguration, (), (override));
292   MOCK_METHOD((void), ReconfigurationComplete, (), (override));
293 
294   MOCK_METHOD((void), OnDestroyed, ());
~MockLeAudioSourceHalClient()295   virtual ~MockLeAudioSourceHalClient() override { OnDestroyed(); }
296 };
297 
298 class UnicastTestNoInit : public Test {
299  protected:
SetUpMockAudioHal()300   void SetUpMockAudioHal() {
301     bluetooth::common::InitFlags::Load(test_flags);
302 
303     /* Since these are returned by the Acquire() methods as unique_ptrs, we
304      * will not free them manually.
305      */
306 
307     owned_mock_le_audio_sink_hal_client_.reset(new NiceMock<MockLeAudioSinkHalClient>());
308     mock_le_audio_sink_hal_client_ =
309         (MockLeAudioSinkHalClient*)owned_mock_le_audio_sink_hal_client_.get();
310 
311     owned_mock_le_audio_source_hal_client_.reset(
312         new NiceMock<MockLeAudioSourceHalClient>());
313     mock_le_audio_source_hal_client_ =
314         (MockLeAudioSourceHalClient*)
315             owned_mock_le_audio_source_hal_client_.get();
316 
317     is_audio_unicast_source_acquired = false;
318     ON_CALL(*mock_le_audio_source_hal_client_, Start(_, _))
319         .WillByDefault(
320             [this](const LeAudioCodecConfiguration& codec_configuration,
321                    LeAudioSourceAudioHalClient::Callbacks* audioReceiver) {
322               unicast_source_hal_cb_ = audioReceiver;
323               return true;
324             });
325     ON_CALL(*mock_le_audio_source_hal_client_, OnDestroyed).WillByDefault([]() {
326       mock_le_audio_source_hal_client_ = nullptr;
327       is_audio_unicast_source_acquired = false;
328     });
329 
330     is_audio_unicast_sink_acquired = false;
331     ON_CALL(*mock_le_audio_sink_hal_client_, Start(_, _))
332         .WillByDefault(
333             [this](const LeAudioCodecConfiguration& codec_configuration,
334                    LeAudioSinkAudioHalClient::Callbacks* audioReceiver) {
335               unicast_sink_hal_cb_ = audioReceiver;
336               return true;
337             });
338     ON_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed).WillByDefault([]() {
339       mock_le_audio_sink_hal_client_ = nullptr;
340       is_audio_unicast_sink_acquired = false;
341     });
342 
343     ON_CALL(*mock_le_audio_sink_hal_client_, SendData)
344         .WillByDefault([](uint8_t* data, uint16_t size) { return size; });
345 
346     // HAL
347     ON_CALL(mock_hal_2_1_verifier, Call()).WillByDefault([]() -> bool {
348       return true;
349     });
350   }
351 
InjectGroupDeviceRemoved(const RawAddress & address,int group_id)352   void InjectGroupDeviceRemoved(const RawAddress& address, int group_id) {
353     group_callbacks_->OnGroupMemberRemoved(address, group_id);
354   }
355 
InjectGroupDeviceAdded(const RawAddress & address,int group_id)356   void InjectGroupDeviceAdded(const RawAddress& address, int group_id) {
357     bluetooth::Uuid uuid = le_audio::uuid::kCapServiceUuid;
358 
359     int group_members_num = 0;
360     for (const auto& [addr, id] : groups) {
361       if (id == group_id) group_members_num++;
362     }
363 
364     bool first_device = (group_members_num == 1);
365     do_in_main_thread(
366         FROM_HERE,
367         base::BindOnce(
368             [](const RawAddress& addr, int group_id, bluetooth::Uuid uuid,
369                bluetooth::groups::DeviceGroupsCallbacks* group_callbacks,
370                bool first_device) {
371               if (first_device) {
372                 group_callbacks->OnGroupAdded(addr, uuid, group_id);
373               } else {
374                 group_callbacks->OnGroupMemberAdded(addr, group_id);
375               }
376             },
377             address, group_id, uuid, base::Unretained(this->group_callbacks_),
378             first_device));
379   }
380 
InjectConnectedEvent(const RawAddress & address,uint16_t conn_id,tGATT_STATUS status=GATT_SUCCESS)381   void InjectConnectedEvent(const RawAddress& address, uint16_t conn_id,
382                             tGATT_STATUS status = GATT_SUCCESS) {
383     ASSERT_NE(conn_id, GATT_INVALID_CONN_ID);
384     tBTA_GATTC_OPEN event_data = {
385         .status = status,
386         .conn_id = conn_id,
387         .client_if = gatt_if,
388         .remote_bda = address,
389         .transport = GATT_TRANSPORT_LE,
390         .mtu = 240,
391     };
392 
393     if (status == GATT_SUCCESS) {
394       ASSERT_NE(peer_devices.count(conn_id), 0u);
395       peer_devices.at(conn_id)->connected = true;
396     }
397 
398     do_in_main_thread(
399         FROM_HERE,
400         base::BindOnce(
401             [](tBTA_GATTC_CBACK* gatt_callback, tBTA_GATTC_OPEN event_data) {
402               gatt_callback(BTA_GATTC_OPEN_EVT, (tBTA_GATTC*)&event_data);
403             },
404             base::Unretained(this->gatt_callback), event_data));
405   }
406 
InjectDisconnectedEvent(uint16_t conn_id,tGATT_DISCONN_REASON reason=GATT_CONN_TERMINATE_LOCAL_HOST)407   void InjectDisconnectedEvent(
408       uint16_t conn_id,
409       tGATT_DISCONN_REASON reason = GATT_CONN_TERMINATE_LOCAL_HOST) {
410     ASSERT_NE(conn_id, GATT_INVALID_CONN_ID);
411     ASSERT_NE(peer_devices.count(conn_id), 0u);
412 
413     tBTA_GATTC_CLOSE event_data = {
414         .status = GATT_SUCCESS,
415         .conn_id = conn_id,
416         .client_if = gatt_if,
417         .remote_bda = peer_devices.at(conn_id)->addr,
418         .reason = reason,
419     };
420 
421     peer_devices.at(conn_id)->connected = false;
422     do_in_main_thread(
423         FROM_HERE,
424         base::BindOnce(
425             [](tBTA_GATTC_CBACK* gatt_callback, tBTA_GATTC_CLOSE event_data) {
426               gatt_callback(BTA_GATTC_CLOSE_EVT, (tBTA_GATTC*)&event_data);
427             },
428             base::Unretained(this->gatt_callback), event_data));
429   }
430 
InjectSearchCompleteEvent(uint16_t conn_id)431   void InjectSearchCompleteEvent(uint16_t conn_id) {
432     ASSERT_NE(conn_id, GATT_INVALID_CONN_ID);
433     tBTA_GATTC_SEARCH_CMPL event_data = {
434         .status = GATT_SUCCESS,
435         .conn_id = conn_id,
436     };
437 
438     do_in_main_thread(FROM_HERE,
439                       base::BindOnce(
440                           [](tBTA_GATTC_CBACK* gatt_callback,
441                              tBTA_GATTC_SEARCH_CMPL event_data) {
442                             gatt_callback(BTA_GATTC_SEARCH_CMPL_EVT,
443                                           (tBTA_GATTC*)&event_data);
444                           },
445                           base::Unretained(this->gatt_callback), event_data));
446   }
447 
InjectNotificationEvent(const RawAddress & test_address,uint16_t conn_id,uint16_t handle,std::vector<uint8_t> value)448   void InjectNotificationEvent(const RawAddress& test_address, uint16_t conn_id,
449                                uint16_t handle, std::vector<uint8_t> value) {
450     ASSERT_NE(conn_id, GATT_INVALID_CONN_ID);
451     tBTA_GATTC_NOTIFY event_data = {
452         .conn_id = conn_id,
453         .bda = test_address,
454         .handle = handle,
455         .len = (uint8_t)value.size(),
456         .is_notify = true,
457     };
458 
459     std::copy(value.begin(), value.end(), event_data.value);
460     do_in_main_thread(
461         FROM_HERE,
462         base::BindOnce(
463             [](tBTA_GATTC_CBACK* gatt_callback, tBTA_GATTC_NOTIFY event_data) {
464               gatt_callback(BTA_GATTC_NOTIF_EVT, (tBTA_GATTC*)&event_data);
465             },
466             base::Unretained(this->gatt_callback), event_data));
467   }
468 
SetUpMockGatt()469   void SetUpMockGatt() {
470     // default action for GetCharacteristic function call
471     ON_CALL(mock_gatt_interface_, GetCharacteristic(_, _))
472         .WillByDefault(
473             Invoke([&](uint16_t conn_id,
474                        uint16_t handle) -> const gatt::Characteristic* {
475               std::list<gatt::Service>& services =
476                   peer_devices.at(conn_id)->services;
477               for (auto const& service : services) {
478                 for (auto const& characteristic : service.characteristics) {
479                   if (characteristic.value_handle == handle) {
480                     return &characteristic;
481                   }
482                 }
483               }
484 
485               return nullptr;
486             }));
487 
488     // default action for GetOwningService function call
489     ON_CALL(mock_gatt_interface_, GetOwningService(_, _))
490         .WillByDefault(Invoke(
491             [&](uint16_t conn_id, uint16_t handle) -> const gatt::Service* {
492               std::list<gatt::Service>& services =
493                   peer_devices.at(conn_id)->services;
494               for (auto const& service : services) {
495                 if (service.handle <= handle && service.end_handle >= handle) {
496                   return &service;
497                 }
498               }
499 
500               return nullptr;
501             }));
502 
503     // default action for ServiceSearchRequest function call
504     ON_CALL(mock_gatt_interface_, ServiceSearchRequest(_, _))
505         .WillByDefault(WithArg<0>(Invoke(
506             [&](uint16_t conn_id) { InjectSearchCompleteEvent(conn_id); })));
507 
508     // default action for GetServices function call
509     ON_CALL(mock_gatt_interface_, GetServices(_))
510         .WillByDefault(WithArg<0>(
511             Invoke([&](uint16_t conn_id) -> std::list<gatt::Service>* {
512               return &peer_devices.at(conn_id)->services;
513             })));
514 
515     // default action for RegisterForNotifications function call
516     ON_CALL(mock_gatt_interface_, RegisterForNotifications(gatt_if, _, _))
517         .WillByDefault(Return(GATT_SUCCESS));
518 
519     // default action for DeregisterForNotifications function call
520     ON_CALL(mock_gatt_interface_, DeregisterForNotifications(gatt_if, _, _))
521         .WillByDefault(Return(GATT_SUCCESS));
522 
523     // default action for WriteDescriptor function call
524     ON_CALL(mock_gatt_queue_, WriteDescriptor(_, _, _, _, _, _))
525         .WillByDefault(Invoke([](uint16_t conn_id, uint16_t handle,
526                                  std::vector<uint8_t> value,
527                                  tGATT_WRITE_TYPE write_type,
528                                  GATT_WRITE_OP_CB cb, void* cb_data) -> void {
529           if (cb)
530             do_in_main_thread(
531                 FROM_HERE,
532                 base::BindOnce(
533                     [](GATT_WRITE_OP_CB cb, uint16_t conn_id, uint16_t handle,
534                        uint16_t len, uint8_t* value, void* cb_data) {
535                       cb(conn_id, GATT_SUCCESS, handle, len, value, cb_data);
536                     },
537                     cb, conn_id, handle, value.size(), value.data(), cb_data));
538         }));
539 
540     global_conn_id = 1;
541     ON_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_DIRECT_CONNECTION, _))
542         .WillByDefault(
543             Invoke([&](tGATT_IF client_if, const RawAddress& remote_bda,
544                        bool is_direct, bool opportunistic) {
545               InjectConnectedEvent(remote_bda, global_conn_id++);
546             }));
547 
548     ON_CALL(mock_gatt_interface_, Close(_))
549         .WillByDefault(Invoke(
550             [&](uint16_t conn_id) { InjectDisconnectedEvent(conn_id); }));
551 
552     // default Characteristic read handler dispatches requests to service mocks
553     ON_CALL(mock_gatt_queue_, ReadCharacteristic(_, _, _, _))
554         .WillByDefault(Invoke([&](uint16_t conn_id, uint16_t handle,
555                                   GATT_READ_OP_CB cb, void* cb_data) {
556           do_in_main_thread(
557               FROM_HERE,
558               base::BindOnce(
559                   [](std::map<uint16_t, std::unique_ptr<NiceMock<MockDeviceWrapper>>>*
560                          peer_devices,
561                      uint16_t conn_id, uint16_t handle, GATT_READ_OP_CB cb,
562                      void* cb_data) -> void {
563                     if (peer_devices->count(conn_id)) {
564                       auto& device = peer_devices->at(conn_id);
565                       auto svc = std::find_if(
566                           device->services.begin(), device->services.end(),
567                           [handle](const gatt::Service& svc) {
568                             return (handle >= svc.handle) &&
569                                    (handle <= svc.end_handle);
570                           });
571                       if (svc == device->services.end()) return;
572 
573                       // Dispatch to mockable handler functions
574                       if (svc->handle == device->csis->start) {
575                         device->csis->OnReadCharacteristic(handle, cb, cb_data);
576                       } else if (svc->handle == device->cas->start) {
577                         device->cas->OnReadCharacteristic(handle, cb, cb_data);
578                       } else if (svc->handle == device->ascs->start) {
579                         device->ascs->OnReadCharacteristic(handle, cb, cb_data);
580                       } else if (svc->handle == device->pacs->start) {
581                         device->pacs->OnReadCharacteristic(handle, cb, cb_data);
582                       }
583                     }
584                   },
585                   &peer_devices, conn_id, handle, cb, cb_data));
586         }));
587   }
588 
SetUpMockGroups()589   void SetUpMockGroups() {
590     MockCsisClient::SetMockInstanceForTesting(&mock_csis_client_module_);
591     MockDeviceGroups::SetMockInstanceForTesting(&mock_groups_module_);
592     MockLeAudioGroupStateMachine::SetMockInstanceForTesting(
593         &mock_state_machine_);
594 
595     ON_CALL(mock_csis_client_module_, Get())
596         .WillByDefault(Return(&mock_csis_client_module_));
597 
598     // Store group callbacks so that we could inject grouping events
599     group_callbacks_ = nullptr;
600     ON_CALL(mock_groups_module_, Initialize(_))
601         .WillByDefault(SaveArg<0>(&group_callbacks_));
602 
603     ON_CALL(mock_groups_module_, GetGroupId(_, _))
604         .WillByDefault([this](const RawAddress& addr, bluetooth::Uuid uuid) {
605           if (groups.find(addr) != groups.end()) return groups.at(addr);
606           return bluetooth::groups::kGroupUnknown;
607         });
608 
609     ON_CALL(mock_groups_module_, RemoveDevice(_, _))
610         .WillByDefault([this](const RawAddress& addr, int group_id_) {
611           int group_id = -1;
612           if (groups.find(addr) != groups.end()) {
613             group_id = groups[addr];
614             groups.erase(addr);
615           }
616           if (group_id < 0) return;
617 
618           do_in_main_thread(
619               FROM_HERE,
620               base::BindOnce(
621                   [](const RawAddress& address, int group_id,
622                      bluetooth::groups::DeviceGroupsCallbacks*
623                          group_callbacks) {
624                     group_callbacks->OnGroupMemberRemoved(address, group_id);
625                   },
626                   addr, group_id, base::Unretained(group_callbacks_)));
627         });
628 
629     // Our test devices have unique LSB - use it for unique grouping when
630     // devices added with a non-CIS context and no grouping info
631     ON_CALL(mock_groups_module_,
632             AddDevice(_, le_audio::uuid::kCapServiceUuid, _))
633         .WillByDefault(
634             [this](const RawAddress& addr,
635                    bluetooth::Uuid uuid = le_audio::uuid::kCapServiceUuid,
636                    int group_id = bluetooth::groups::kGroupUnknown) -> int {
637               if (group_id == bluetooth::groups::kGroupUnknown) {
638                 /* Generate group id from address */
639                 groups[addr] = addr.address[RawAddress::kLength - 1];
640                 group_id = groups[addr];
641               } else {
642                 groups[addr] = group_id;
643               }
644 
645               InjectGroupDeviceAdded(addr, groups[addr]);
646               return addr.address[RawAddress::kLength - 1];
647             });
648 
649     ON_CALL(mock_state_machine_, Initialize(_))
650         .WillByDefault(SaveArg<0>(&state_machine_callbacks_));
651 
652     ON_CALL(mock_state_machine_, ConfigureStream(_, _, _, _))
653         .WillByDefault(
654             [this](LeAudioDeviceGroup* group,
655                    types::LeAudioContextType context_type,
656                    types::BidirectionalPair<types::AudioContexts>
657                        metadata_context_types,
658                    types::BidirectionalPair<std::vector<uint8_t>> ccid_lists) {
659               bool isReconfiguration = group->IsPendingConfiguration();
660 
661               /* This shall be called only for user reconfiguration */
662               if (!isReconfiguration) return false;
663 
664               /* Do what ReleaseCisIds(group) does: start */
665               LeAudioDevice* leAudioDevice = group->GetFirstDevice();
666               while (leAudioDevice != nullptr) {
667                 for (auto& ase : leAudioDevice->ases_) {
668                   ase.cis_id = le_audio::kInvalidCisId;
669                 }
670                 leAudioDevice = group->GetNextDevice(leAudioDevice);
671               }
672               group->CigClearCis();
673               /* end */
674 
675               if (!group->Configure(context_type, metadata_context_types,
676                                     ccid_lists)) {
677                 LOG_ERROR(
678                     "Could not configure ASEs for group %d content type %d",
679                     group->group_id_, int(context_type));
680 
681                 return false;
682               }
683 
684               group->CigGenerateCisIds(context_type);
685 
686               for (LeAudioDevice* device = group->GetFirstDevice();
687                    device != nullptr; device = group->GetNextDevice(device)) {
688                 for (auto& ase : device->ases_) {
689                   ase.data_path_state = types::AudioStreamDataPathState::IDLE;
690                   ase.active = false;
691                   ase.state =
692                       types::AseState::BTA_LE_AUDIO_ASE_STATE_CODEC_CONFIGURED;
693                 }
694               }
695 
696               // Inject the state
697               group->SetTargetState(
698                   types::AseState::BTA_LE_AUDIO_ASE_STATE_CODEC_CONFIGURED);
699               group->SetState(group->GetTargetState());
700               group->ClearPendingConfiguration();
701               do_in_main_thread(
702                   FROM_HERE,
703                   base::BindOnce(
704                       [](int group_id,
705                          le_audio::LeAudioGroupStateMachine::Callbacks*
706                              state_machine_callbacks) {
707                         state_machine_callbacks->StatusReportCb(
708                             group_id, GroupStreamStatus::CONFIGURED_BY_USER);
709                       },
710                       group->group_id_,
711                       base::Unretained(this->state_machine_callbacks_)));
712               return true;
713             });
714 
715     ON_CALL(mock_state_machine_, AttachToStream(_, _))
716         .WillByDefault([](LeAudioDeviceGroup* group,
717                           LeAudioDevice* leAudioDevice) {
718           if (group->GetState() !=
719               types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING) {
720             return false;
721           }
722 
723           group->Configure(group->GetConfigurationContextType(),
724                            group->GetMetadataContexts());
725           if (!group->CigAssignCisIds(leAudioDevice)) return false;
726           group->CigAssignCisConnHandlesToAses(leAudioDevice);
727 
728           auto* stream_conf = &group->stream_conf;
729 
730           for (auto& ase : leAudioDevice->ases_) {
731             if (!ase.active) continue;
732 
733             // And also skip the ase establishment procedure which should
734             // be tested as part of the state machine unit tests
735             ase.data_path_state =
736                 types::AudioStreamDataPathState::DATA_PATH_ESTABLISHED;
737             ase.state = types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING;
738 
739             uint16_t cis_conn_hdl = ase.cis_conn_hdl;
740 
741             /* Copied from state_machine.cc ProcessHciNotifSetupIsoDataPath */
742             if (ase.direction == le_audio::types::kLeAudioDirectionSource) {
743               auto iter = std::find_if(stream_conf->source_streams.begin(),
744                                        stream_conf->source_streams.end(),
745                                        [cis_conn_hdl](auto& pair) {
746                                          return cis_conn_hdl == pair.first;
747                                        });
748 
749               if (iter == stream_conf->source_streams.end()) {
750                 stream_conf->source_streams.emplace_back(
751                     std::make_pair(ase.cis_conn_hdl,
752                                    *ase.codec_config.audio_channel_allocation));
753 
754                 stream_conf->source_num_of_devices++;
755                 stream_conf->source_num_of_channels +=
756                     ase.codec_config.channel_count;
757 
758                 LOG_INFO(
759                     " Added Source Stream Configuration. CIS Connection "
760                     "Handle: %d"
761                     ", Audio Channel Allocation: %d"
762                     ", Source Number Of Devices: %d"
763                     ", Source Number Of Channels: %d",
764                     +ase.cis_conn_hdl,
765                     +(*ase.codec_config.audio_channel_allocation),
766                     +stream_conf->source_num_of_devices,
767                     +stream_conf->source_num_of_channels);
768               }
769             } else {
770               auto iter = std::find_if(stream_conf->sink_streams.begin(),
771                                        stream_conf->sink_streams.end(),
772                                        [cis_conn_hdl](auto& pair) {
773                                          return cis_conn_hdl == pair.first;
774                                        });
775 
776               if (iter == stream_conf->sink_streams.end()) {
777                 stream_conf->sink_streams.emplace_back(
778                     std::make_pair(ase.cis_conn_hdl,
779                                    *ase.codec_config.audio_channel_allocation));
780 
781                 stream_conf->sink_num_of_devices++;
782                 stream_conf->sink_num_of_channels +=
783                     ase.codec_config.channel_count;
784 
785                 LOG_INFO(
786                     " Added Sink Stream Configuration. CIS Connection Handle: "
787                     "%d"
788                     ", Audio Channel Allocation: %d"
789                     ", Sink Number Of Devices: %d"
790                     ", Sink Number Of Channels: %d",
791                     +ase.cis_conn_hdl,
792                     +(*ase.codec_config.audio_channel_allocation),
793                     +stream_conf->sink_num_of_devices,
794                     +stream_conf->sink_num_of_channels);
795               }
796             }
797           }
798 
799           return true;
800         });
801 
802     ON_CALL(mock_state_machine_, StartStream(_, _, _, _))
803         .WillByDefault([this](LeAudioDeviceGroup* group,
804                               types::LeAudioContextType context_type,
805                               types::BidirectionalPair<types::AudioContexts>
806                                   metadata_context_types,
807                               types::BidirectionalPair<std::vector<uint8_t>>
808                                   ccid_lists) {
809           /* Do nothing if already streaming - the implementation would
810            * probably update the metadata.
811            */
812           if (group->GetState() ==
813               types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING) {
814             return true;
815           }
816 
817           /* Do what ReleaseCisIds(group) does: start */
818           LeAudioDevice* leAudioDevice = group->GetFirstDevice();
819           while (leAudioDevice != nullptr) {
820             for (auto& ase : leAudioDevice->ases_) {
821               ase.cis_id = le_audio::kInvalidCisId;
822             }
823             leAudioDevice = group->GetNextDevice(leAudioDevice);
824           }
825           group->CigClearCis();
826           /* end */
827 
828           if (!group->Configure(context_type, metadata_context_types,
829                                 ccid_lists)) {
830             LOG(ERROR) << __func__ << ", failed to set ASE configuration";
831             return false;
832           }
833 
834           if (group->GetState() ==
835               types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE) {
836             group->CigGenerateCisIds(context_type);
837 
838             std::vector<uint16_t> conn_handles;
839             for (uint8_t i = 0; i < (uint8_t)(group->cises_.size()); i++) {
840               conn_handles.push_back(iso_con_counter_++);
841             }
842             group->CigAssignCisConnHandles(conn_handles);
843             for (LeAudioDevice* device = group->GetFirstActiveDevice();
844                  device != nullptr;
845                  device = group->GetNextActiveDevice(device)) {
846               if (!group->CigAssignCisIds(device)) return false;
847               group->CigAssignCisConnHandlesToAses(device);
848             }
849           }
850 
851           auto* stream_conf = &group->stream_conf;
852 
853           // Fake ASE configuration
854           for (LeAudioDevice* device = group->GetFirstActiveDevice();
855                device != nullptr; device = group->GetNextActiveDevice(device)) {
856             for (auto& ase : device->ases_) {
857               if (!ase.active) continue;
858 
859               // And also skip the ase establishment procedure which should
860               // be tested as part of the state machine unit tests
861               ase.data_path_state =
862                   types::AudioStreamDataPathState::DATA_PATH_ESTABLISHED;
863               ase.state = types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING;
864 
865               uint16_t cis_conn_hdl = ase.cis_conn_hdl;
866 
867               /* Copied from state_machine.cc ProcessHciNotifSetupIsoDataPath */
868               if (ase.direction == le_audio::types::kLeAudioDirectionSource) {
869                 auto iter = std::find_if(stream_conf->source_streams.begin(),
870                                          stream_conf->source_streams.end(),
871                                          [cis_conn_hdl](auto& pair) {
872                                            return cis_conn_hdl == pair.first;
873                                          });
874 
875                 if (iter == stream_conf->source_streams.end()) {
876                   stream_conf->source_streams.emplace_back(std::make_pair(
877                       ase.cis_conn_hdl,
878                       *ase.codec_config.audio_channel_allocation));
879 
880                   stream_conf->source_num_of_devices++;
881                   stream_conf->source_num_of_channels +=
882                       ase.codec_config.channel_count;
883                   stream_conf->source_audio_channel_allocation |=
884                       *ase.codec_config.audio_channel_allocation;
885 
886                   if (stream_conf->source_sample_frequency_hz == 0) {
887                     stream_conf->source_sample_frequency_hz =
888                         ase.codec_config.GetSamplingFrequencyHz();
889                   } else {
890                     ASSERT_LOG(stream_conf->source_sample_frequency_hz ==
891                                    ase.codec_config.GetSamplingFrequencyHz(),
892                                "sample freq mismatch: %d!=%d",
893                                stream_conf->source_sample_frequency_hz,
894                                ase.codec_config.GetSamplingFrequencyHz());
895                   }
896 
897                   if (stream_conf->source_octets_per_codec_frame == 0) {
898                     stream_conf->source_octets_per_codec_frame =
899                         *ase.codec_config.octets_per_codec_frame;
900                   } else {
901                     ASSERT_LOG(stream_conf->source_octets_per_codec_frame ==
902                                    *ase.codec_config.octets_per_codec_frame,
903                                "octets per frame mismatch: %d!=%d",
904                                stream_conf->source_octets_per_codec_frame,
905                                *ase.codec_config.octets_per_codec_frame);
906                   }
907 
908                   if (stream_conf->source_codec_frames_blocks_per_sdu == 0) {
909                     stream_conf->source_codec_frames_blocks_per_sdu =
910                         *ase.codec_config.codec_frames_blocks_per_sdu;
911                   } else {
912                     ASSERT_LOG(
913                         stream_conf->source_codec_frames_blocks_per_sdu ==
914                             *ase.codec_config.codec_frames_blocks_per_sdu,
915                         "codec_frames_blocks_per_sdu: %d!=%d",
916                         stream_conf->source_codec_frames_blocks_per_sdu,
917                         *ase.codec_config.codec_frames_blocks_per_sdu);
918                   }
919 
920                   LOG_INFO(
921                       " Added Source Stream Configuration. CIS Connection "
922                       "Handle: %d"
923                       ", Audio Channel Allocation: %d"
924                       ", Source Number Of Devices: %d"
925                       ", Source Number Of Channels: %d",
926                       +ase.cis_conn_hdl,
927                       +(*ase.codec_config.audio_channel_allocation),
928                       +stream_conf->source_num_of_devices,
929                       +stream_conf->source_num_of_channels);
930                 }
931               } else {
932                 auto iter = std::find_if(stream_conf->sink_streams.begin(),
933                                          stream_conf->sink_streams.end(),
934                                          [cis_conn_hdl](auto& pair) {
935                                            return cis_conn_hdl == pair.first;
936                                          });
937 
938                 if (iter == stream_conf->sink_streams.end()) {
939                   stream_conf->sink_streams.emplace_back(std::make_pair(
940                       ase.cis_conn_hdl,
941                       *ase.codec_config.audio_channel_allocation));
942 
943                   stream_conf->sink_num_of_devices++;
944                   stream_conf->sink_num_of_channels +=
945                       ase.codec_config.channel_count;
946 
947                   stream_conf->sink_audio_channel_allocation |=
948                       *ase.codec_config.audio_channel_allocation;
949 
950                   if (stream_conf->sink_sample_frequency_hz == 0) {
951                     stream_conf->sink_sample_frequency_hz =
952                         ase.codec_config.GetSamplingFrequencyHz();
953                   } else {
954                     ASSERT_LOG(stream_conf->sink_sample_frequency_hz ==
955                                    ase.codec_config.GetSamplingFrequencyHz(),
956                                "sample freq mismatch: %d!=%d",
957                                stream_conf->sink_sample_frequency_hz,
958                                ase.codec_config.GetSamplingFrequencyHz());
959                   }
960 
961                   if (stream_conf->sink_octets_per_codec_frame == 0) {
962                     stream_conf->sink_octets_per_codec_frame =
963                         *ase.codec_config.octets_per_codec_frame;
964                   } else {
965                     ASSERT_LOG(stream_conf->sink_octets_per_codec_frame ==
966                                    *ase.codec_config.octets_per_codec_frame,
967                                "octets per frame mismatch: %d!=%d",
968                                stream_conf->sink_octets_per_codec_frame,
969                                *ase.codec_config.octets_per_codec_frame);
970                   }
971 
972                   if (stream_conf->sink_codec_frames_blocks_per_sdu == 0) {
973                     stream_conf->sink_codec_frames_blocks_per_sdu =
974                         *ase.codec_config.codec_frames_blocks_per_sdu;
975                   } else {
976                     ASSERT_LOG(
977                         stream_conf->sink_codec_frames_blocks_per_sdu ==
978                             *ase.codec_config.codec_frames_blocks_per_sdu,
979                         "codec_frames_blocks_per_sdu: %d!=%d",
980                         stream_conf->sink_codec_frames_blocks_per_sdu,
981                         *ase.codec_config.codec_frames_blocks_per_sdu);
982                   }
983 
984                   LOG_INFO(
985                       " Added Sink Stream Configuration. CIS Connection "
986                       "Handle: %d"
987                       ", Audio Channel Allocation: %d"
988                       ", Sink Number Of Devices: %d"
989                       ", Sink Number Of Channels: %d",
990                       +ase.cis_conn_hdl,
991                       +(*ase.codec_config.audio_channel_allocation),
992                       +stream_conf->sink_num_of_devices,
993                       +stream_conf->sink_num_of_channels);
994                 }
995               }
996             }
997           }
998 
999           // Inject the state
1000           group->SetTargetState(
1001               types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
1002           group->SetState(group->GetTargetState());
1003           streaming_groups[group->group_id_] = group;
1004 
1005           /* Assume CIG is created */
1006           group->cig_state_ = le_audio::types::CigState::CREATED;
1007 
1008           do_in_main_thread(
1009               FROM_HERE, base::BindOnce(
1010                              [](int group_id,
1011                                 le_audio::LeAudioGroupStateMachine::Callbacks*
1012                                     state_machine_callbacks) {
1013                                state_machine_callbacks->StatusReportCb(
1014                                    group_id, GroupStreamStatus::STREAMING);
1015                              },
1016                              group->group_id_,
1017                              base::Unretained(this->state_machine_callbacks_)));
1018           return true;
1019         });
1020 
1021     ON_CALL(mock_state_machine_, SuspendStream(_))
1022         .WillByDefault([this](LeAudioDeviceGroup* group) {
1023           // Fake ASE state
1024           for (LeAudioDevice* device = group->GetFirstDevice();
1025                device != nullptr; device = group->GetNextDevice(device)) {
1026             for (auto& ase : device->ases_) {
1027               ase.data_path_state =
1028                   types::AudioStreamDataPathState::CIS_ESTABLISHED;
1029               ase.active = false;
1030               ase.state =
1031                   types::AseState::BTA_LE_AUDIO_ASE_STATE_QOS_CONFIGURED;
1032             }
1033           }
1034 
1035           // Inject the state
1036           group->SetTargetState(
1037               types::AseState::BTA_LE_AUDIO_ASE_STATE_QOS_CONFIGURED);
1038           group->SetState(group->GetTargetState());
1039           state_machine_callbacks_->StatusReportCb(
1040               group->group_id_, GroupStreamStatus::SUSPENDED);
1041         });
1042 
1043     ON_CALL(mock_state_machine_, ProcessHciNotifAclDisconnected(_, _))
1044         .WillByDefault([this](LeAudioDeviceGroup* group,
1045                               LeAudioDevice* leAudioDevice) {
1046           if (!group) return;
1047           auto* stream_conf = &group->stream_conf;
1048           if (!stream_conf->sink_streams.empty() ||
1049               !stream_conf->source_streams.empty()) {
1050             stream_conf->sink_streams.erase(
1051                 std::remove_if(stream_conf->sink_streams.begin(),
1052                                stream_conf->sink_streams.end(),
1053                                [leAudioDevice, &stream_conf](auto& pair) {
1054                                  auto ases = leAudioDevice->GetAsesByCisConnHdl(
1055                                      pair.first);
1056                                  if (ases.sink) {
1057                                    stream_conf->sink_num_of_devices--;
1058                                    stream_conf->sink_num_of_channels -=
1059                                        ases.sink->codec_config.channel_count;
1060 
1061                                    LOG_INFO(
1062                                        ", Source Number Of Devices: %d"
1063                                        ", Source Number Of Channels: %d",
1064                                        +stream_conf->source_num_of_devices,
1065                                        +stream_conf->source_num_of_channels);
1066                                  }
1067                                  return ases.sink;
1068                                }),
1069                 stream_conf->sink_streams.end());
1070 
1071             stream_conf->source_streams.erase(
1072                 std::remove_if(stream_conf->source_streams.begin(),
1073                                stream_conf->source_streams.end(),
1074                                [leAudioDevice, &stream_conf](auto& pair) {
1075                                  auto ases = leAudioDevice->GetAsesByCisConnHdl(
1076                                      pair.first);
1077                                  if (ases.source) {
1078                                    stream_conf->source_num_of_devices--;
1079                                    stream_conf->source_num_of_channels -=
1080                                        ases.source->codec_config.channel_count;
1081 
1082                                    LOG_INFO(
1083                                        ", Source Number Of Devices: %d"
1084                                        ", Source Number Of Channels: %d",
1085                                        +stream_conf->source_num_of_devices,
1086                                        +stream_conf->source_num_of_channels);
1087                                  }
1088                                  return ases.source;
1089                                }),
1090                 stream_conf->source_streams.end());
1091           }
1092 
1093           group->CigUnassignCis(leAudioDevice);
1094 
1095           if (group->IsEmpty()) {
1096             group->cig_state_ = le_audio::types::CigState::NONE;
1097             InjectCigRemoved(group->group_id_);
1098           }
1099         });
1100 
1101     ON_CALL(mock_state_machine_, ProcessHciNotifCisDisconnected(_, _, _))
1102         .WillByDefault(
1103             [](LeAudioDeviceGroup* group, LeAudioDevice* leAudioDevice,
1104                const bluetooth::hci::iso_manager::cis_disconnected_evt* event) {
1105               if (!group) return;
1106               auto ases_pair =
1107                   leAudioDevice->GetAsesByCisConnHdl(event->cis_conn_hdl);
1108               if (ases_pair.sink) {
1109                 ases_pair.sink->data_path_state =
1110                     types::AudioStreamDataPathState::CIS_ASSIGNED;
1111                 ases_pair.sink->active = false;
1112               }
1113               if (ases_pair.source) {
1114                 ases_pair.source->active = false;
1115                 ases_pair.source->data_path_state =
1116                     types::AudioStreamDataPathState::CIS_ASSIGNED;
1117               }
1118               /* Invalidate stream configuration if needed */
1119               auto* stream_conf = &group->stream_conf;
1120               if (!stream_conf->sink_streams.empty() ||
1121                   !stream_conf->source_streams.empty()) {
1122                 stream_conf->sink_streams.erase(
1123                     std::remove_if(
1124                         stream_conf->sink_streams.begin(),
1125                         stream_conf->sink_streams.end(),
1126                         [leAudioDevice, &stream_conf](auto& pair) {
1127                           auto ases =
1128                               leAudioDevice->GetAsesByCisConnHdl(pair.first);
1129 
1130                           LOG_INFO(
1131                               ", sink ase to delete. Cis handle: %d"
1132                               ", ase pointer: %p",
1133                               +(int)(pair.first), +ases.sink);
1134                           if (ases.sink) {
1135                             stream_conf->sink_num_of_devices--;
1136                             stream_conf->sink_num_of_channels -=
1137                                 ases.sink->codec_config.channel_count;
1138 
1139                             LOG_INFO(
1140                                 " Sink Number Of Devices: %d"
1141                                 ", Sink Number Of Channels: %d",
1142                                 +stream_conf->sink_num_of_devices,
1143                                 +stream_conf->sink_num_of_channels);
1144                           }
1145                           return ases.sink;
1146                         }),
1147                     stream_conf->sink_streams.end());
1148 
1149                 stream_conf->source_streams.erase(
1150                     std::remove_if(
1151                         stream_conf->source_streams.begin(),
1152                         stream_conf->source_streams.end(),
1153                         [leAudioDevice, &stream_conf](auto& pair) {
1154                           auto ases =
1155                               leAudioDevice->GetAsesByCisConnHdl(pair.first);
1156 
1157                           LOG_INFO(
1158                               ", source to delete. Cis handle: %d"
1159                               ", ase pointer: %p",
1160                               +(int)(pair.first), ases.source);
1161                           if (ases.source) {
1162                             stream_conf->source_num_of_devices--;
1163                             stream_conf->source_num_of_channels -=
1164                                 ases.source->codec_config.channel_count;
1165 
1166                             LOG_INFO(
1167                                 ", Source Number Of Devices: %d"
1168                                 ", Source Number Of Channels: %d",
1169                                 +stream_conf->source_num_of_devices,
1170                                 +stream_conf->source_num_of_channels);
1171                           }
1172                           return ases.source;
1173                         }),
1174                     stream_conf->source_streams.end());
1175               }
1176 
1177               group->CigUnassignCis(leAudioDevice);
1178             });
1179 
1180     ON_CALL(mock_state_machine_, StopStream(_))
1181         .WillByDefault([this](LeAudioDeviceGroup* group) {
1182           for (LeAudioDevice* device = group->GetFirstDevice();
1183                device != nullptr; device = group->GetNextDevice(device)) {
1184             /* Invalidate stream configuration if needed */
1185             auto* stream_conf = &group->stream_conf;
1186             if (!stream_conf->sink_streams.empty() ||
1187                 !stream_conf->source_streams.empty()) {
1188               stream_conf->sink_streams.erase(
1189                   std::remove_if(stream_conf->sink_streams.begin(),
1190                                  stream_conf->sink_streams.end(),
1191                                  [device, &stream_conf](auto& pair) {
1192                                    auto ases =
1193                                        device->GetAsesByCisConnHdl(pair.first);
1194 
1195                                    LOG_INFO(
1196                                        ", sink ase to delete. Cis handle: %d"
1197                                        ", ase pointer: %p",
1198                                        +(int)(pair.first), +ases.sink);
1199                                    if (ases.sink) {
1200                                      stream_conf->sink_num_of_devices--;
1201                                      stream_conf->sink_num_of_channels -=
1202                                          ases.sink->codec_config.channel_count;
1203 
1204                                      LOG_INFO(
1205                                          " Sink Number Of Devices: %d"
1206                                          ", Sink Number Of Channels: %d",
1207                                          +stream_conf->sink_num_of_devices,
1208                                          +stream_conf->sink_num_of_channels);
1209                                    }
1210                                    return ases.sink;
1211                                  }),
1212                   stream_conf->sink_streams.end());
1213 
1214               stream_conf->source_streams.erase(
1215                   std::remove_if(
1216                       stream_conf->source_streams.begin(),
1217                       stream_conf->source_streams.end(),
1218                       [device, &stream_conf](auto& pair) {
1219                         auto ases = device->GetAsesByCisConnHdl(pair.first);
1220 
1221                         LOG_INFO(
1222                             ", source to delete. Cis handle: %d"
1223                             ", ase pointer: %p",
1224                             +(int)(pair.first), +ases.source);
1225                         if (ases.source) {
1226                           stream_conf->source_num_of_devices--;
1227                           stream_conf->source_num_of_channels -=
1228                               ases.source->codec_config.channel_count;
1229 
1230                           LOG_INFO(
1231                               ", Source Number Of Devices: %d"
1232                               ", Source Number Of Channels: %d",
1233                               +stream_conf->source_num_of_devices,
1234                               +stream_conf->source_num_of_channels);
1235                         }
1236                         return ases.source;
1237                       }),
1238                   stream_conf->source_streams.end());
1239             }
1240 
1241             group->CigUnassignCis(device);
1242 
1243             for (auto& ase : device->ases_) {
1244               ase.data_path_state = types::AudioStreamDataPathState::IDLE;
1245               ase.active = false;
1246               ase.state = types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE;
1247               ase.cis_id = 0;
1248               ase.cis_conn_hdl = 0;
1249             }
1250           }
1251 
1252           // Inject the state
1253           group->SetTargetState(types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE);
1254           group->SetState(group->GetTargetState());
1255           state_machine_callbacks_->StatusReportCb(
1256               group->group_id_, GroupStreamStatus::RELEASING);
1257 
1258           do_in_main_thread(
1259               FROM_HERE,
1260               base::BindOnce(
1261                   [](le_audio::LeAudioGroupStateMachine::Callbacks* cb,
1262                      int group_id) {
1263                     cb->StatusReportCb(group_id, GroupStreamStatus::IDLE);
1264                   },
1265                   state_machine_callbacks_, group->group_id_));
1266         });
1267   }
1268 
SetUp()1269   void SetUp() override {
1270     init_message_loop_thread();
1271     ON_CALL(controller_interface_, SupportsBleConnectedIsochronousStreamCentral)
1272         .WillByDefault(Return(true));
1273     ON_CALL(controller_interface_,
1274             SupportsBleConnectedIsochronousStreamPeripheral)
1275         .WillByDefault(Return(true));
1276 
1277     controller::SetMockControllerInterface(&controller_interface_);
1278     bluetooth::manager::SetMockBtmInterface(&mock_btm_interface_);
1279     gatt::SetMockBtaGattInterface(&mock_gatt_interface_);
1280     gatt::SetMockBtaGattQueue(&mock_gatt_queue_);
1281     bluetooth::storage::SetMockBtifStorageInterface(&mock_btif_storage_);
1282 
1283     iso_manager_ = bluetooth::hci::IsoManager::GetInstance();
1284     ASSERT_NE(iso_manager_, nullptr);
1285     iso_manager_->Start();
1286 
1287     mock_iso_manager_ = MockIsoManager::GetInstance();
1288     ON_CALL(*mock_iso_manager_, RegisterCigCallbacks(_))
1289         .WillByDefault(SaveArg<0>(&cig_callbacks_));
1290 
1291     SetUpMockAudioHal();
1292     SetUpMockGroups();
1293     SetUpMockGatt();
1294 
1295     supported_snk_context_types_ = 0xffff;
1296     supported_src_context_types_ = 0xffff;
1297     le_audio::AudioSetConfigurationProvider::Initialize();
1298     ASSERT_FALSE(LeAudioClient::IsLeAudioClientRunning());
1299   }
1300 
TearDown()1301   void TearDown() override {
1302     if (is_audio_unicast_source_acquired) {
1303       if (unicast_source_hal_cb_ != nullptr) {
1304         EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop).Times(1);
1305       }
1306       EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(1);
1307     }
1308 
1309     if (is_audio_unicast_sink_acquired) {
1310       if (unicast_sink_hal_cb_ != nullptr) {
1311         EXPECT_CALL(*mock_le_audio_sink_hal_client_, Stop).Times(1);
1312       }
1313       EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(1);
1314     }
1315 
1316     // Message loop cleanup should wait for all the 'till now' scheduled calls
1317     // so it should be called right at the very begginning of teardown.
1318     cleanup_message_loop_thread();
1319 
1320     // This is required since Stop() and Cleanup() may trigger some callbacks or
1321     // drop unique pointers to mocks we have raw pointer for and we want to
1322     // verify them all.
1323     Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
1324 
1325     if (LeAudioClient::IsLeAudioClientRunning()) {
1326       EXPECT_CALL(mock_gatt_interface_, AppDeregister(gatt_if)).Times(1);
1327       LeAudioClient::Cleanup(base::DoNothing());
1328       ASSERT_FALSE(LeAudioClient::IsLeAudioClientRunning());
1329     }
1330 
1331     owned_mock_le_audio_sink_hal_client_.reset();
1332     owned_mock_le_audio_source_hal_client_.reset();
1333 
1334     if (le_audio::AudioSetConfigurationProvider::Get())
1335       le_audio::AudioSetConfigurationProvider::Cleanup();
1336 
1337     iso_manager_->Stop();
1338   }
1339 
1340  protected:
1341   class MockDeviceWrapper {
1342     class IGattHandlers {
1343      public:
1344       // IGattHandlers() = default;
1345       virtual ~IGattHandlers() = default;
1346       virtual void OnReadCharacteristic(uint16_t handle, GATT_READ_OP_CB cb,
1347                                         void* cb_data) = 0;
1348       virtual void OnWriteCharacteristic(uint16_t handle,
1349                                          std::vector<uint8_t> value,
1350                                          tGATT_WRITE_TYPE write_type,
1351                                          GATT_WRITE_OP_CB cb,
1352                                          void* cb_data) = 0;
1353     };
1354 
1355    public:
1356     struct csis_mock : public IGattHandlers {
1357       uint16_t start = 0;
1358       uint16_t end = 0;
1359       uint16_t sirk_char = 0;
1360       uint16_t sirk_ccc = 0;
1361       uint16_t size_char = 0;
1362       uint16_t size_ccc = 0;
1363       uint16_t lock_char = 0;
1364       uint16_t lock_ccc = 0;
1365       uint16_t rank_char = 0;
1366 
1367       int rank = 0;
1368       int size = 0;
1369 
1370       MOCK_METHOD((void), OnReadCharacteristic,
1371                   (uint16_t handle, GATT_READ_OP_CB cb, void* cb_data),
1372                   (override));
1373       MOCK_METHOD((void), OnWriteCharacteristic,
1374                   (uint16_t handle, std::vector<uint8_t> value,
1375                    tGATT_WRITE_TYPE write_type, GATT_WRITE_OP_CB cb,
1376                    void* cb_data),
1377                   (override));
1378     };
1379 
1380     struct cas_mock : public IGattHandlers {
1381       uint16_t start = 0;
1382       uint16_t end = 0;
1383       uint16_t csis_include = 0;
1384 
1385       MOCK_METHOD((void), OnReadCharacteristic,
1386                   (uint16_t handle, GATT_READ_OP_CB cb, void* cb_data),
1387                   (override));
1388       MOCK_METHOD((void), OnWriteCharacteristic,
1389                   (uint16_t handle, std::vector<uint8_t> value,
1390                    tGATT_WRITE_TYPE write_type, GATT_WRITE_OP_CB cb,
1391                    void* cb_data),
1392                   (override));
1393     };
1394 
1395     struct pacs_mock : public IGattHandlers {
1396       uint16_t start = 0;
1397       uint16_t sink_pac_char = 0;
1398       uint16_t sink_pac_ccc = 0;
1399       uint16_t sink_audio_loc_char = 0;
1400       uint16_t sink_audio_loc_ccc = 0;
1401       uint16_t source_pac_char = 0;
1402       uint16_t source_pac_ccc = 0;
1403       uint16_t source_audio_loc_char = 0;
1404       uint16_t source_audio_loc_ccc = 0;
1405       uint16_t avail_contexts_char = 0;
1406       uint16_t avail_contexts_ccc = 0;
1407       uint16_t supp_contexts_char = 0;
1408       uint16_t supp_contexts_ccc = 0;
1409       uint16_t end = 0;
1410 
1411       MOCK_METHOD((void), OnReadCharacteristic,
1412                   (uint16_t handle, GATT_READ_OP_CB cb, void* cb_data),
1413                   (override));
1414       MOCK_METHOD((void), OnWriteCharacteristic,
1415                   (uint16_t handle, std::vector<uint8_t> value,
1416                    tGATT_WRITE_TYPE write_type, GATT_WRITE_OP_CB cb,
1417                    void* cb_data),
1418                   (override));
1419     };
1420 
1421     struct ascs_mock : public IGattHandlers {
1422       uint16_t start = 0;
1423       uint16_t sink_ase_char[max_num_of_ases] = {0};
1424       uint16_t sink_ase_ccc[max_num_of_ases] = {0};
1425       uint16_t source_ase_char[max_num_of_ases] = {0};
1426       uint16_t source_ase_ccc[max_num_of_ases] = {0};
1427       uint16_t ctp_char = 0;
1428       uint16_t ctp_ccc = 0;
1429       uint16_t end = 0;
1430 
1431       MOCK_METHOD((void), OnReadCharacteristic,
1432                   (uint16_t handle, GATT_READ_OP_CB cb, void* cb_data),
1433                   (override));
1434       MOCK_METHOD((void), OnWriteCharacteristic,
1435                   (uint16_t handle, std::vector<uint8_t> value,
1436                    tGATT_WRITE_TYPE write_type, GATT_WRITE_OP_CB cb,
1437                    void* cb_data),
1438                   (override));
1439     };
1440 
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)1441     MockDeviceWrapper(RawAddress addr, const std::list<gatt::Service>& services,
1442                       std::unique_ptr<NiceMock<MockDeviceWrapper::csis_mock>> csis,
1443                       std::unique_ptr<NiceMock<MockDeviceWrapper::cas_mock>> cas,
1444                       std::unique_ptr<NiceMock<MockDeviceWrapper::ascs_mock>> ascs,
1445                       std::unique_ptr<NiceMock<MockDeviceWrapper::pacs_mock>> pacs)
1446         : addr(addr) {
1447       this->services = services;
1448       this->csis = std::move(csis);
1449       this->cas = std::move(cas);
1450       this->ascs = std::move(ascs);
1451       this->pacs = std::move(pacs);
1452     }
1453 
~MockDeviceWrapper()1454     ~MockDeviceWrapper() {
1455       Mock::VerifyAndClearExpectations(csis.get());
1456       Mock::VerifyAndClearExpectations(cas.get());
1457       Mock::VerifyAndClearExpectations(ascs.get());
1458       Mock::VerifyAndClearExpectations(pacs.get());
1459     }
1460 
1461     RawAddress addr;
1462     bool connected = false;
1463 
1464     // A list of services and their useful params
1465     std::list<gatt::Service> services;
1466     std::unique_ptr<csis_mock> csis;
1467     std::unique_ptr<cas_mock> cas;
1468     std::unique_ptr<ascs_mock> ascs;
1469     std::unique_ptr<pacs_mock> pacs;
1470   };
1471 
SyncOnMainLoop()1472   void SyncOnMainLoop() {
1473     // Wait for the main loop to flush
1474     // WARNING: Not tested with Timers pushing periodic tasks to the main loop
1475     while (num_async_tasks > 0)
1476       ;
1477   }
1478 
ConnectLeAudio(const RawAddress & address,bool isEncrypted=true)1479   void ConnectLeAudio(const RawAddress& address, bool isEncrypted = true) {
1480     // by default indicate link as encrypted
1481     ON_CALL(mock_btm_interface_, BTM_IsEncrypted(address, _))
1482         .WillByDefault(DoAll(Return(isEncrypted)));
1483 
1484     EXPECT_CALL(mock_gatt_interface_,
1485                 Open(gatt_if, address, BTM_BLE_DIRECT_CONNECTION, _))
1486         .Times(1);
1487 
1488     do_in_main_thread(
1489         FROM_HERE, base::Bind(&LeAudioClient::Connect,
1490                               base::Unretained(LeAudioClient::Get()), address));
1491 
1492     SyncOnMainLoop();
1493     Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
1494   }
1495 
DisconnectLeAudio(const RawAddress & address,uint16_t conn_id)1496   void DisconnectLeAudio(const RawAddress& address, uint16_t conn_id) {
1497     SyncOnMainLoop();
1498     EXPECT_CALL(mock_gatt_interface_, Close(conn_id)).Times(1);
1499     EXPECT_CALL(mock_audio_hal_client_callbacks_,
1500                 OnConnectionState(ConnectionState::DISCONNECTED, address))
1501         .Times(1);
1502     do_in_main_thread(
1503         FROM_HERE, base::Bind(&LeAudioClient::Disconnect,
1504                               base::Unretained(LeAudioClient::Get()), address));
1505   }
1506 
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)1507   void ConnectCsisDevice(const RawAddress& addr, uint16_t conn_id,
1508                          uint32_t sink_audio_allocation,
1509                          uint32_t source_audio_allocation, uint8_t group_size,
1510                          int group_id, uint8_t rank,
1511                          bool connect_through_csis = false,
1512                          bool new_device = true) {
1513     SetSampleDatabaseEarbudsValid(conn_id, addr, sink_audio_allocation,
1514                                   source_audio_allocation, default_channel_cnt,
1515                                   default_channel_cnt,
1516                                   0x0004, /* source sample freq 16khz */
1517                                   true,   /*add_csis*/
1518                                   true,   /*add_cas*/
1519                                   true,   /*add_pacs*/
1520                                   true,   /*add_ascs*/
1521                                   group_size, rank);
1522     EXPECT_CALL(mock_audio_hal_client_callbacks_,
1523                 OnConnectionState(ConnectionState::CONNECTED, addr))
1524         .Times(1);
1525 
1526     if (new_device) {
1527       EXPECT_CALL(mock_audio_hal_client_callbacks_,
1528                   OnGroupNodeStatus(addr, group_id, GroupNodeStatus::ADDED))
1529           .Times(1);
1530     }
1531 
1532     if (connect_through_csis) {
1533       // Add it the way CSIS would do: add to group and then connect
1534       do_in_main_thread(
1535           FROM_HERE,
1536           base::Bind(&LeAudioClient::GroupAddNode,
1537                      base::Unretained(LeAudioClient::Get()), group_id, addr));
1538       ConnectLeAudio(addr);
1539     } else {
1540       // The usual connect
1541       // Since device has CSIS, lets add it here to groups already now
1542       groups[addr] = group_id;
1543       ConnectLeAudio(addr);
1544       InjectGroupDeviceAdded(addr, group_id);
1545     }
1546   }
1547 
ConnectNonCsisDevice(const RawAddress & addr,uint16_t conn_id,uint32_t sink_audio_allocation,uint32_t source_audio_allocation)1548   void ConnectNonCsisDevice(const RawAddress& addr, uint16_t conn_id,
1549                             uint32_t sink_audio_allocation,
1550                             uint32_t source_audio_allocation) {
1551     SetSampleDatabaseEarbudsValid(
1552         conn_id, addr, sink_audio_allocation, source_audio_allocation,
1553         default_channel_cnt, default_channel_cnt, 0x0004,
1554         /* source sample freq 16khz */ false, /*add_csis*/
1555         true,                                 /*add_cas*/
1556         true,                                 /*add_pacs*/
1557         true,                                 /*add_ascs*/
1558         0, 0);
1559     EXPECT_CALL(mock_audio_hal_client_callbacks_,
1560                 OnConnectionState(ConnectionState::CONNECTED, addr))
1561         .Times(1);
1562 
1563     ConnectLeAudio(addr);
1564   }
1565 
UpdateMetadata(audio_usage_t usage,audio_content_type_t content_type,bool reconfigure_existing_stream=false)1566   void UpdateMetadata(audio_usage_t usage, audio_content_type_t content_type,
1567                       bool reconfigure_existing_stream = false) {
1568     std::vector<struct playback_track_metadata> source_metadata = {
1569         {{AUDIO_USAGE_UNKNOWN, AUDIO_CONTENT_TYPE_UNKNOWN, 0},
1570          {AUDIO_USAGE_UNKNOWN, AUDIO_CONTENT_TYPE_UNKNOWN, 0}}};
1571 
1572     source_metadata[0].usage = usage;
1573     source_metadata[0].content_type = content_type;
1574 
1575     if (reconfigure_existing_stream) {
1576       Expectation reconfigure = EXPECT_CALL(*mock_le_audio_source_hal_client_,
1577                                             SuspendedForReconfiguration())
1578                                     .Times(1);
1579       EXPECT_CALL(*mock_le_audio_source_hal_client_, CancelStreamingRequest())
1580           .Times(1);
1581       EXPECT_CALL(*mock_le_audio_source_hal_client_, ReconfigurationComplete())
1582           .Times(1)
1583           .After(reconfigure);
1584     } else {
1585       EXPECT_CALL(*mock_le_audio_source_hal_client_,
1586                   SuspendedForReconfiguration())
1587           .Times(0);
1588       EXPECT_CALL(*mock_le_audio_source_hal_client_, ReconfigurationComplete())
1589           .Times(0);
1590     }
1591 
1592     ASSERT_NE(unicast_source_hal_cb_, nullptr);
1593     unicast_source_hal_cb_->OnAudioMetadataUpdate(source_metadata);
1594   }
1595 
UpdateSourceMetadata(audio_source_t audio_source)1596   void UpdateSourceMetadata(audio_source_t audio_source) {
1597     std::vector<struct record_track_metadata> sink_metadata = {
1598         {{AUDIO_SOURCE_INVALID, 0.5, AUDIO_DEVICE_NONE, "00:11:22:33:44:55"},
1599          {AUDIO_SOURCE_MIC, 0.7, AUDIO_DEVICE_OUT_BLE_HEADSET,
1600           "AA:BB:CC:DD:EE:FF"}}};
1601 
1602     sink_metadata[1].source = audio_source;
1603     unicast_sink_hal_cb_->OnAudioMetadataUpdate(sink_metadata);
1604   }
1605 
SinkAudioResume(void)1606   void SinkAudioResume(void) {
1607     EXPECT_CALL(*mock_le_audio_source_hal_client_, ConfirmStreamingRequest())
1608         .Times(1);
1609     do_in_main_thread(FROM_HERE,
1610                       base::BindOnce(
1611                           [](LeAudioSourceAudioHalClient::Callbacks* cb) {
1612                             cb->OnAudioResume();
1613                           },
1614                           unicast_source_hal_cb_));
1615 
1616     SyncOnMainLoop();
1617     Mock::VerifyAndClearExpectations(&*mock_le_audio_source_hal_client_);
1618   }
1619 
StartStreaming(audio_usage_t usage,audio_content_type_t content_type,int group_id,audio_source_t audio_source=AUDIO_SOURCE_INVALID,bool reconfigure_existing_stream=false)1620   void StartStreaming(audio_usage_t usage, audio_content_type_t content_type,
1621                       int group_id,
1622                       audio_source_t audio_source = AUDIO_SOURCE_INVALID,
1623                       bool reconfigure_existing_stream = false) {
1624     ASSERT_NE(unicast_source_hal_cb_, nullptr);
1625 
1626     UpdateMetadata(usage, content_type, reconfigure_existing_stream);
1627     if (audio_source != AUDIO_SOURCE_INVALID) {
1628       UpdateSourceMetadata(audio_source);
1629     }
1630 
1631     /* Stream has been automatically restarted on UpdateMetadata */
1632     if (reconfigure_existing_stream) return;
1633 
1634     SinkAudioResume();
1635     SyncOnMainLoop();
1636     Mock::VerifyAndClearExpectations(&mock_state_machine_);
1637 
1638     if (usage == AUDIO_USAGE_VOICE_COMMUNICATION ||
1639         audio_source != AUDIO_SOURCE_INVALID) {
1640       ASSERT_NE(unicast_sink_hal_cb_, nullptr);
1641       do_in_main_thread(FROM_HERE,
1642                         base::BindOnce(
1643                             [](LeAudioSinkAudioHalClient::Callbacks* cb) {
1644                               cb->OnAudioResume();
1645                             },
1646                             unicast_sink_hal_cb_));
1647     }
1648   }
1649 
StopStreaming(int group_id,bool suspend_source=false)1650   void StopStreaming(int group_id, bool suspend_source = false) {
1651     ASSERT_NE(unicast_source_hal_cb_, nullptr);
1652 
1653     /* TODO We should have a way to confirm Stop() otherwise, audio framework
1654      * might have different state that it is in the le_audio code - as tearing
1655      * down CISes might take some time
1656      */
1657     std::promise<void> do_suspend_sink_promise;
1658     auto do_suspend_sink_future = do_suspend_sink_promise.get_future();
1659     /* It's enough to call only one resume even if it'll be bi-directional
1660      * streaming. First suspend will trigger GroupStop.
1661      *
1662      * There is no - 'only source receiver' scenario (e.g. single microphone).
1663      * If there will be such test oriented scenario, such resume choose logic
1664      * should be applied.
1665      */
1666     unicast_source_hal_cb_->OnAudioSuspend(std::move(do_suspend_sink_promise));
1667     do_suspend_sink_future.wait();
1668 
1669     if (suspend_source) {
1670       ASSERT_NE(unicast_sink_hal_cb_, nullptr);
1671       std::promise<void> do_suspend_source_promise;
1672       auto do_suspend_source_future = do_suspend_source_promise.get_future();
1673       unicast_sink_hal_cb_->OnAudioSuspend(
1674           std::move(do_suspend_source_promise));
1675       do_suspend_source_future.wait();
1676     }
1677   }
1678 
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)1679   void set_sample_database(uint16_t conn_id, RawAddress addr,
1680                            std::unique_ptr<NiceMock<MockDeviceWrapper::csis_mock>> csis,
1681                            std::unique_ptr<NiceMock<MockDeviceWrapper::cas_mock>> cas,
1682                            std::unique_ptr<NiceMock<MockDeviceWrapper::ascs_mock>> ascs,
1683                            std::unique_ptr<NiceMock<MockDeviceWrapper::pacs_mock>> pacs) {
1684     gatt::DatabaseBuilder bob;
1685 
1686     /* Generic Access Service */
1687     bob.AddService(0x0001, 0x0003, Uuid::From16Bit(0x1800), true);
1688     /* Device Name Char. */
1689     bob.AddCharacteristic(0x0002, 0x0003, Uuid::From16Bit(0x2a00),
1690                           GATT_CHAR_PROP_BIT_READ);
1691 
1692     if (csis->start) {
1693       bool is_primary = true;
1694       bob.AddService(csis->start, csis->end, bluetooth::csis::kCsisServiceUuid,
1695                      is_primary);
1696       if (csis->sirk_char) {
1697         bob.AddCharacteristic(
1698             csis->sirk_char, csis->sirk_char + 1,
1699             bluetooth::csis::kCsisSirkUuid,
1700             GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
1701         if (csis->sirk_ccc)
1702           bob.AddDescriptor(csis->sirk_ccc,
1703                             Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
1704       }
1705 
1706       if (csis->size_char) {
1707         bob.AddCharacteristic(
1708             csis->size_char, csis->size_char + 1,
1709             bluetooth::csis::kCsisSizeUuid,
1710             GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
1711         if (csis->size_ccc)
1712           bob.AddDescriptor(csis->size_ccc,
1713                             Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
1714       }
1715 
1716       if (csis->lock_char) {
1717         bob.AddCharacteristic(csis->lock_char, csis->lock_char + 1,
1718                               bluetooth::csis::kCsisLockUuid,
1719                               GATT_CHAR_PROP_BIT_READ |
1720                                   GATT_CHAR_PROP_BIT_NOTIFY |
1721                                   GATT_CHAR_PROP_BIT_WRITE);
1722         if (csis->lock_ccc)
1723           bob.AddDescriptor(csis->lock_ccc,
1724                             Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
1725       }
1726 
1727       if (csis->rank_char)
1728         bob.AddCharacteristic(csis->rank_char, csis->rank_char + 1,
1729                               bluetooth::csis::kCsisRankUuid,
1730                               GATT_CHAR_PROP_BIT_READ);
1731     }
1732 
1733     if (cas->start) {
1734       bool is_primary = true;
1735       bob.AddService(cas->start, cas->end, le_audio::uuid::kCapServiceUuid,
1736                      is_primary);
1737       // Include CSIS service inside
1738       if (cas->csis_include)
1739         bob.AddIncludedService(cas->csis_include,
1740                                bluetooth::csis::kCsisServiceUuid, csis->start,
1741                                csis->end);
1742     }
1743 
1744     if (pacs->start) {
1745       bool is_primary = true;
1746       bob.AddService(pacs->start, pacs->end,
1747                      le_audio::uuid::kPublishedAudioCapabilityServiceUuid,
1748                      is_primary);
1749 
1750       if (pacs->sink_pac_char) {
1751         bob.AddCharacteristic(
1752             pacs->sink_pac_char, pacs->sink_pac_char + 1,
1753             le_audio::uuid::kSinkPublishedAudioCapabilityCharacteristicUuid,
1754             GATT_CHAR_PROP_BIT_READ);
1755         if (pacs->sink_pac_ccc)
1756           bob.AddDescriptor(pacs->sink_pac_ccc,
1757                             Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
1758       }
1759 
1760       if (pacs->sink_audio_loc_char) {
1761         bob.AddCharacteristic(
1762             pacs->sink_audio_loc_char, pacs->sink_audio_loc_char + 1,
1763             le_audio::uuid::kSinkAudioLocationCharacteristicUuid,
1764             GATT_CHAR_PROP_BIT_READ);
1765         if (pacs->sink_audio_loc_ccc)
1766           bob.AddDescriptor(pacs->sink_audio_loc_ccc,
1767                             Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
1768       }
1769 
1770       if (pacs->source_pac_char) {
1771         bob.AddCharacteristic(
1772             pacs->source_pac_char, pacs->source_pac_char + 1,
1773             le_audio::uuid::kSourcePublishedAudioCapabilityCharacteristicUuid,
1774             GATT_CHAR_PROP_BIT_READ);
1775         if (pacs->source_pac_ccc)
1776           bob.AddDescriptor(pacs->source_pac_ccc,
1777                             Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
1778       }
1779 
1780       if (pacs->source_audio_loc_char) {
1781         bob.AddCharacteristic(
1782             pacs->source_audio_loc_char, pacs->source_audio_loc_char + 1,
1783             le_audio::uuid::kSourceAudioLocationCharacteristicUuid,
1784             GATT_CHAR_PROP_BIT_READ);
1785         if (pacs->source_audio_loc_ccc)
1786           bob.AddDescriptor(pacs->source_audio_loc_ccc,
1787                             Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
1788       }
1789 
1790       if (pacs->avail_contexts_char) {
1791         bob.AddCharacteristic(
1792             pacs->avail_contexts_char, pacs->avail_contexts_char + 1,
1793             le_audio::uuid::kAudioContextAvailabilityCharacteristicUuid,
1794             GATT_CHAR_PROP_BIT_READ);
1795         if (pacs->avail_contexts_ccc)
1796           bob.AddDescriptor(pacs->avail_contexts_ccc,
1797                             Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
1798       }
1799 
1800       if (pacs->supp_contexts_char) {
1801         bob.AddCharacteristic(
1802             pacs->supp_contexts_char, pacs->supp_contexts_char + 1,
1803             le_audio::uuid::kAudioSupportedContextCharacteristicUuid,
1804             GATT_CHAR_PROP_BIT_READ);
1805         if (pacs->supp_contexts_ccc)
1806           bob.AddDescriptor(pacs->supp_contexts_ccc,
1807                             Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
1808       }
1809     }
1810 
1811     if (ascs->start) {
1812       bool is_primary = true;
1813       bob.AddService(ascs->start, ascs->end,
1814                      le_audio::uuid::kAudioStreamControlServiceUuid,
1815                      is_primary);
1816       for (int i = 0; i < max_num_of_ases; i++) {
1817         if (ascs->sink_ase_char[i]) {
1818           bob.AddCharacteristic(ascs->sink_ase_char[i],
1819                                 ascs->sink_ase_char[i] + 1,
1820                                 le_audio::uuid::kSinkAudioStreamEndpointUuid,
1821                                 GATT_CHAR_PROP_BIT_READ);
1822           if (ascs->sink_ase_ccc[i])
1823             bob.AddDescriptor(ascs->sink_ase_ccc[i],
1824                               Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
1825         }
1826         if (ascs->source_ase_char[i]) {
1827           bob.AddCharacteristic(ascs->source_ase_char[i],
1828                                 ascs->source_ase_char[i] + 1,
1829                                 le_audio::uuid::kSourceAudioStreamEndpointUuid,
1830                                 GATT_CHAR_PROP_BIT_READ);
1831           if (ascs->source_ase_ccc[i])
1832             bob.AddDescriptor(ascs->source_ase_ccc[i],
1833                               Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
1834         }
1835       }
1836       if (ascs->ctp_char) {
1837         bob.AddCharacteristic(
1838             ascs->ctp_char, ascs->ctp_char + 1,
1839             le_audio::uuid::kAudioStreamEndpointControlPointCharacteristicUuid,
1840             GATT_CHAR_PROP_BIT_READ);
1841         if (ascs->ctp_ccc)
1842           bob.AddDescriptor(ascs->ctp_ccc,
1843                             Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
1844       }
1845     }
1846 
1847     // Assign conn_id to a certain device - this does not mean it is connected
1848     auto dev_wrapper = std::make_unique<NiceMock<MockDeviceWrapper>>(
1849         addr, bob.Build().Services(), std::move(csis), std::move(cas),
1850         std::move(ascs), std::move(pacs));
1851     peer_devices.emplace(conn_id, std::move(dev_wrapper));
1852   }
1853 
SetSampleDatabaseEmpty(uint16_t conn_id,RawAddress addr)1854   void SetSampleDatabaseEmpty(uint16_t conn_id, RawAddress addr) {
1855     auto csis = std::make_unique<NiceMock<MockDeviceWrapper::csis_mock>>();
1856     auto cas = std::make_unique<NiceMock<MockDeviceWrapper::cas_mock>>();
1857     auto pacs = std::make_unique<NiceMock<MockDeviceWrapper::pacs_mock>>();
1858     auto ascs = std::make_unique<NiceMock<MockDeviceWrapper::ascs_mock>>();
1859     set_sample_database(conn_id, addr, std::move(csis), std::move(cas),
1860                         std::move(ascs), std::move(pacs));
1861   }
1862 
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)1863   void SetSampleDatabaseEarbudsValid(
1864       uint16_t conn_id, RawAddress addr, uint32_t sink_audio_allocation,
1865       uint32_t source_audio_allocation, uint8_t sink_channel_cnt = 0x03,
1866       uint8_t source_channel_cnt = 0x03, uint16_t sample_freq_mask = 0x0004,
1867       bool add_csis = true, bool add_cas = true, bool add_pacs = true,
1868       int add_ascs_cnt = 1, uint8_t set_size = 2, uint8_t rank = 1) {
1869     auto csis = std::make_unique<NiceMock<MockDeviceWrapper::csis_mock>>();
1870     if (add_csis) {
1871       // attribute handles
1872       csis->start = 0x0010;
1873       csis->sirk_char = 0x0020;
1874       csis->sirk_ccc = 0x0022;
1875       csis->size_char = 0x0023;
1876       csis->size_ccc = 0x0025;
1877       csis->lock_char = 0x0026;
1878       csis->lock_ccc = 0x0028;
1879       csis->rank_char = 0x0029;
1880       csis->end = 0x0030;
1881       // other params
1882       csis->size = set_size;
1883       csis->rank = rank;
1884     }
1885 
1886     auto cas = std::make_unique<NiceMock<MockDeviceWrapper::cas_mock>>();
1887     if (add_cas) {
1888       // attribute handles
1889       cas->start = 0x0040;
1890       if (add_csis) cas->csis_include = 0x0041;
1891       cas->end = 0x0050;
1892       // other params
1893     }
1894 
1895     auto pacs = std::make_unique<NiceMock<MockDeviceWrapper::pacs_mock>>();
1896     if (add_pacs) {
1897       // attribute handles
1898       pacs->start = 0x0060;
1899       pacs->sink_pac_char = 0x0061;
1900       pacs->sink_pac_ccc = 0x0063;
1901       pacs->sink_audio_loc_char = 0x0064;
1902       pacs->sink_audio_loc_ccc = 0x0066;
1903       pacs->source_pac_char = 0x0067;
1904       pacs->source_pac_ccc = 0x0069;
1905       pacs->source_audio_loc_char = 0x0070;
1906       pacs->source_audio_loc_ccc = 0x0072;
1907       pacs->avail_contexts_char = 0x0073;
1908       pacs->avail_contexts_ccc = 0x0075;
1909       pacs->supp_contexts_char = 0x0076;
1910       pacs->supp_contexts_ccc = 0x0078;
1911       pacs->end = 0x0080;
1912       // other params
1913     }
1914 
1915     auto ascs = std::make_unique<NiceMock<MockDeviceWrapper::ascs_mock>>();
1916     if (add_ascs_cnt > 0) {
1917       // attribute handles
1918       ascs->start = 0x0090;
1919       uint16_t handle = 0x0091;
1920       for (int i = 0; i < add_ascs_cnt; i++) {
1921         if (sink_audio_allocation != 0) {
1922           ascs->sink_ase_char[i] = handle;
1923           handle += 2;
1924           ascs->sink_ase_ccc[i] = handle;
1925           handle++;
1926         }
1927 
1928         if (source_audio_allocation != 0) {
1929           ascs->source_ase_char[i] = handle;
1930           handle += 2;
1931           ascs->source_ase_ccc[i] = handle;
1932           handle++;
1933         }
1934       }
1935       ascs->ctp_char = handle;
1936       handle += 2;
1937       ascs->ctp_ccc = handle;
1938       handle++;
1939       ascs->end = handle;
1940       // other params
1941     }
1942 
1943     set_sample_database(conn_id, addr, std::move(csis), std::move(cas),
1944                         std::move(ascs), std::move(pacs));
1945 
1946     if (add_pacs) {
1947       uint8_t snk_allocation[4];
1948       uint8_t src_allocation[4];
1949 
1950       snk_allocation[0] = (uint8_t)(sink_audio_allocation);
1951       snk_allocation[1] = (uint8_t)(sink_audio_allocation >> 8);
1952       snk_allocation[2] = (uint8_t)(sink_audio_allocation >> 16);
1953       snk_allocation[3] = (uint8_t)(sink_audio_allocation >> 24);
1954 
1955       src_allocation[0] = (uint8_t)(source_audio_allocation);
1956       src_allocation[1] = (uint8_t)(source_audio_allocation >> 8);
1957       src_allocation[2] = (uint8_t)(source_audio_allocation >> 16);
1958       src_allocation[3] = (uint8_t)(source_audio_allocation >> 24);
1959 
1960       uint8_t sample_freq[2];
1961       sample_freq[0] = (uint8_t)(sample_freq_mask);
1962       sample_freq[1] = (uint8_t)(sample_freq_mask >> 8);
1963 
1964       // Set pacs default read values
1965       ON_CALL(*peer_devices.at(conn_id)->pacs, OnReadCharacteristic(_, _, _))
1966           .WillByDefault(
1967               [this, conn_id, snk_allocation, src_allocation, sample_freq,
1968                sink_channel_cnt, source_channel_cnt](
1969                   uint16_t handle, GATT_READ_OP_CB cb, void* cb_data) {
1970                 auto& pacs = peer_devices.at(conn_id)->pacs;
1971                 std::vector<uint8_t> value;
1972                 if (handle == pacs->sink_pac_char + 1) {
1973                   value = {
1974                       // Num records
1975                       0x02,
1976                       // Codec_ID
1977                       0x06,
1978                       0x00,
1979                       0x00,
1980                       0x00,
1981                       0x00,
1982                       // Codec Spec. Caps. Len
1983                       0x10,
1984                       0x03, /* sample freq */
1985                       0x01,
1986                       sample_freq[0],
1987                       sample_freq[1],
1988                       0x02,
1989                       0x02, /* frame duration */
1990                       0x03,
1991                       0x02, /* channel count */
1992                       0x03,
1993                       sink_channel_cnt,
1994                       0x05,
1995                       0x04,
1996                       0x1E,
1997                       0x00,
1998                       0x78,
1999                       0x00,
2000                       // Metadata Length
2001                       0x00,
2002                       // Codec_ID
2003                       0x06,
2004                       0x00,
2005                       0x00,
2006                       0x00,
2007                       0x00,
2008                       // Codec Spec. Caps. Len
2009                       0x10,
2010                       0x03, /* sample freq */
2011                       0x01,
2012                       0x80, /* 48kHz */
2013                       0x00,
2014                       0x02, /* frame duration */
2015                       0x02,
2016                       0x03,
2017                       0x02, /* channel count */
2018                       0x03,
2019                       sink_channel_cnt,
2020                       0x05, /* octects per frame */
2021                       0x04,
2022                       0x78,
2023                       0x00,
2024                       0x78,
2025                       0x00,
2026                       // Metadata Length
2027                       0x00,
2028                   };
2029                 } else if (handle == pacs->sink_audio_loc_char + 1) {
2030                   value = {
2031                       // Audio Locations
2032                       snk_allocation[0],
2033                       snk_allocation[1],
2034                       snk_allocation[2],
2035                       snk_allocation[3],
2036                   };
2037                 } else if (handle == pacs->source_pac_char + 1) {
2038                   value = {
2039                       // Num records
2040                       0x02,
2041                       // Codec_ID
2042                       0x06,
2043                       0x00,
2044                       0x00,
2045                       0x00,
2046                       0x00,
2047                       // Codec Spec. Caps. Len
2048                       0x10,
2049                       0x03,
2050                       0x01,
2051                       sample_freq[0],
2052                       sample_freq[1],
2053                       0x02,
2054                       0x02,
2055                       0x03,
2056                       0x02,
2057                       0x03,
2058                       source_channel_cnt,
2059                       0x05,
2060                       0x04,
2061                       0x1E,
2062                       0x00,
2063                       0x78,
2064                       0x00,
2065                       // Metadata Length
2066                       0x00,
2067                       // Codec_ID
2068                       0x06,
2069                       0x00,
2070                       0x00,
2071                       0x00,
2072                       0x00,
2073                       // Codec Spec. Caps. Len
2074                       0x10,
2075                       0x03,
2076                       0x01,
2077                       0x24,
2078                       0x00,
2079                       0x02,
2080                       0x02,
2081                       0x03,
2082                       0x02,
2083                       0x03,
2084                       source_channel_cnt,
2085                       0x05,
2086                       0x04,
2087                       0x1E,
2088                       0x00,
2089                       0x50,
2090                       0x00,
2091                       // Metadata Length
2092                       0x00,
2093                   };
2094                 } else if (handle == pacs->source_audio_loc_char + 1) {
2095                   value = {
2096                       // Audio Locations
2097                       src_allocation[0],
2098                       src_allocation[1],
2099                       src_allocation[2],
2100                       src_allocation[3],
2101                   };
2102                 } else if (handle == pacs->avail_contexts_char + 1) {
2103                   value = {
2104                       // Sink Avail Contexts
2105                       (uint8_t)(supported_snk_context_types_),
2106                       (uint8_t)(supported_snk_context_types_ >> 8),
2107                       // Source Avail Contexts
2108                       (uint8_t)(supported_src_context_types_),
2109                       (uint8_t)(supported_src_context_types_ >> 8),
2110                   };
2111                 } else if (handle == pacs->supp_contexts_char + 1) {
2112                   value = {
2113                       // Sink Avail Contexts
2114                       (uint8_t)(supported_snk_context_types_),
2115                       (uint8_t)(supported_snk_context_types_ >> 8),
2116                       // Source Avail Contexts
2117                       (uint8_t)(supported_src_context_types_),
2118                       (uint8_t)(supported_src_context_types_ >> 8),
2119                   };
2120                 }
2121                 cb(conn_id, GATT_SUCCESS, handle, value.size(), value.data(),
2122                    cb_data);
2123               });
2124     }
2125 
2126     if (add_ascs_cnt > 0) {
2127       // Set ascs default read values
2128       ON_CALL(*peer_devices.at(conn_id)->ascs, OnReadCharacteristic(_, _, _))
2129           .WillByDefault([this, conn_id](uint16_t handle, GATT_READ_OP_CB cb,
2130                                          void* cb_data) {
2131             auto& ascs = peer_devices.at(conn_id)->ascs;
2132             std::vector<uint8_t> value;
2133             bool is_ase_sink_request = false;
2134             bool is_ase_src_request = false;
2135             uint8_t idx;
2136             for (idx = 0; idx < max_num_of_ases; idx++) {
2137               if (handle == ascs->sink_ase_char[idx] + 1) {
2138                 is_ase_sink_request = true;
2139                 break;
2140               }
2141               if (handle == ascs->source_ase_char[idx] + 1) {
2142                 is_ase_src_request = true;
2143                 break;
2144               }
2145             }
2146 
2147             if (is_ase_sink_request) {
2148               value = {
2149                   // ASE ID
2150                   static_cast<uint8_t>(idx + 1),
2151                   // State
2152                   static_cast<uint8_t>(
2153                       le_audio::types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE),
2154                   // No Additional ASE params for IDLE state
2155               };
2156             } else if (is_ase_src_request) {
2157               value = {
2158                   // ASE ID
2159                   static_cast<uint8_t>(idx + 6),
2160                   // State
2161                   static_cast<uint8_t>(
2162                       le_audio::types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE),
2163                   // No Additional ASE params for IDLE state
2164               };
2165             }
2166             cb(conn_id, GATT_SUCCESS, handle, value.size(), value.data(),
2167                cb_data);
2168           });
2169     }
2170   }
2171 
TestAudioDataTransfer(int group_id,uint8_t cis_count_out,uint8_t cis_count_in,int data_len,int in_data_len=40)2172   void TestAudioDataTransfer(int group_id, uint8_t cis_count_out,
2173                              uint8_t cis_count_in, int data_len,
2174                              int in_data_len = 40) {
2175     ASSERT_NE(unicast_source_hal_cb_, nullptr);
2176 
2177     // Expect two channels ISO Data to be sent
2178     std::vector<uint16_t> handles;
2179     EXPECT_CALL(*mock_iso_manager_, SendIsoData(_, _, _))
2180         .Times(cis_count_out)
2181         .WillRepeatedly(
2182             [&handles](uint16_t iso_handle, const uint8_t* data,
2183                        uint16_t data_len) { handles.push_back(iso_handle); });
2184     std::vector<uint8_t> data(data_len);
2185     unicast_source_hal_cb_->OnAudioDataReady(data);
2186 
2187     // Inject microphone data from group
2188     EXPECT_CALL(*mock_le_audio_sink_hal_client_, SendData(_, _))
2189         .Times(cis_count_in > 0 ? 1 : 0);
2190     ASSERT_EQ(streaming_groups.count(group_id), 1u);
2191 
2192     if (cis_count_in) {
2193       ASSERT_NE(unicast_sink_hal_cb_, nullptr);
2194 
2195       auto group = streaming_groups.at(group_id);
2196       for (LeAudioDevice* device = group->GetFirstDevice(); device != nullptr;
2197            device = group->GetNextDevice(device)) {
2198         for (auto& ase : device->ases_) {
2199           if (ase.direction == le_audio::types::kLeAudioDirectionSource) {
2200             InjectIncomingIsoData(group_id, ase.cis_conn_hdl, in_data_len);
2201             --cis_count_in;
2202             if (!cis_count_in) break;
2203           }
2204         }
2205         if (!cis_count_in) break;
2206       }
2207     }
2208 
2209     SyncOnMainLoop();
2210     std::sort(handles.begin(), handles.end());
2211     ASSERT_EQ(cis_count_in, 0);
2212     handles.clear();
2213 
2214     Mock::VerifyAndClearExpectations(mock_iso_manager_);
2215   }
2216 
InjectIncomingIsoData(uint16_t cig_id,uint16_t cis_con_hdl,size_t payload_size)2217   void InjectIncomingIsoData(uint16_t cig_id, uint16_t cis_con_hdl,
2218                              size_t payload_size) {
2219     BT_HDR* bt_hdr = (BT_HDR*)malloc(sizeof(BT_HDR) + payload_size);
2220 
2221     bt_hdr->offset = 0;
2222     bt_hdr->len = payload_size;
2223 
2224     bluetooth::hci::iso_manager::cis_data_evt cis_evt;
2225     cis_evt.cig_id = cig_id;
2226     cis_evt.cis_conn_hdl = cis_con_hdl;
2227     cis_evt.ts = 0;
2228     cis_evt.evt_lost = 0;
2229     cis_evt.p_msg = bt_hdr;
2230 
2231     ASSERT_NE(cig_callbacks_, nullptr);
2232     cig_callbacks_->OnCisEvent(
2233         bluetooth::hci::iso_manager::kIsoEventCisDataAvailable, &cis_evt);
2234     free(bt_hdr);
2235   }
2236 
InjectCisDisconnected(uint16_t cig_id,uint16_t cis_con_hdl,uint8_t reason=0)2237   void InjectCisDisconnected(uint16_t cig_id, uint16_t cis_con_hdl,
2238                              uint8_t reason = 0) {
2239     bluetooth::hci::iso_manager::cis_disconnected_evt cis_evt;
2240     cis_evt.cig_id = cig_id;
2241     cis_evt.cis_conn_hdl = cis_con_hdl;
2242     cis_evt.reason = reason;
2243 
2244     ASSERT_NE(cig_callbacks_, nullptr);
2245     cig_callbacks_->OnCisEvent(
2246         bluetooth::hci::iso_manager::kIsoEventCisDisconnected, &cis_evt);
2247   }
2248 
InjectCigRemoved(uint8_t cig_id)2249   void InjectCigRemoved(uint8_t cig_id) {
2250     bluetooth::hci::iso_manager::cig_remove_cmpl_evt evt;
2251     evt.status = 0;
2252     evt.cig_id = cig_id;
2253 
2254     ASSERT_NE(cig_callbacks_, nullptr);
2255     cig_callbacks_->OnCisEvent(
2256         bluetooth::hci::iso_manager::kIsoEventCigOnRemoveCmpl, &evt);
2257   }
2258 
2259   NiceMock<MockAudioHalClientCallbacks> mock_audio_hal_client_callbacks_;
2260   LeAudioSourceAudioHalClient::Callbacks* unicast_source_hal_cb_ = nullptr;
2261   LeAudioSinkAudioHalClient::Callbacks* unicast_sink_hal_cb_ = nullptr;
2262 
2263   uint8_t default_channel_cnt = 0x03;
2264   uint8_t default_ase_cnt = 1;
2265 
2266   NiceMock<MockCsisClient> mock_csis_client_module_;
2267   NiceMock<MockDeviceGroups> mock_groups_module_;
2268   bluetooth::groups::DeviceGroupsCallbacks* group_callbacks_;
2269   NiceMock<MockLeAudioGroupStateMachine> mock_state_machine_;
2270 
2271   NiceMock<MockFunction<void()>> mock_storage_load;
2272   NiceMock<MockFunction<bool()>> mock_hal_2_1_verifier;
2273 
2274   NiceMock<controller::MockControllerInterface> controller_interface_;
2275   NiceMock<bluetooth::manager::MockBtmInterface> mock_btm_interface_;
2276   NiceMock<gatt::MockBtaGattInterface> mock_gatt_interface_;
2277   NiceMock<gatt::MockBtaGattQueue> mock_gatt_queue_;
2278   tBTA_GATTC_CBACK* gatt_callback;
2279   const uint8_t gatt_if = 0xfe;
2280   uint16_t global_conn_id = 1;
2281   le_audio::LeAudioGroupStateMachine::Callbacks* state_machine_callbacks_;
2282   std::map<int, LeAudioDeviceGroup*> streaming_groups;
2283 
2284   bluetooth::hci::IsoManager* iso_manager_;
2285   MockIsoManager* mock_iso_manager_;
2286   bluetooth::hci::iso_manager::CigCallbacks* cig_callbacks_ = nullptr;
2287   uint16_t iso_con_counter_ = 1;
2288 
2289   uint16_t supported_snk_context_types_ = 0xffff;
2290   uint16_t supported_src_context_types_ = 0xffff;
2291 
2292   NiceMock<bluetooth::storage::MockBtifStorageInterface> mock_btif_storage_;
2293 
2294   std::map<uint16_t, std::unique_ptr<NiceMock<MockDeviceWrapper>>> peer_devices;
2295   std::list<int> group_locks;
2296   std::map<RawAddress, int> groups;
2297 };
2298 
2299 class UnicastTest : public UnicastTestNoInit {
2300  protected:
SetUp()2301   void SetUp() override {
2302     UnicastTestNoInit::SetUp();
2303 
2304     EXPECT_CALL(mock_hal_2_1_verifier, Call()).Times(1);
2305     EXPECT_CALL(mock_storage_load, Call()).Times(1);
2306 
2307     std::vector<::bluetooth::le_audio::btle_audio_codec_config_t>
2308         framework_encode_preference;
2309     BtaAppRegisterCallback app_register_callback;
2310     EXPECT_CALL(mock_gatt_interface_, AppRegister(_, _, _))
2311         .WillOnce(DoAll(SaveArg<0>(&gatt_callback),
2312                         SaveArg<1>(&app_register_callback)));
2313     LeAudioClient::Initialize(
2314         &mock_audio_hal_client_callbacks_,
2315         base::Bind([](MockFunction<void()>* foo) { foo->Call(); },
2316                    &mock_storage_load),
2317         base::Bind([](MockFunction<bool()>* foo) { return foo->Call(); },
2318                    &mock_hal_2_1_verifier),
2319         framework_encode_preference);
2320 
2321     SyncOnMainLoop();
2322     ASSERT_TRUE(gatt_callback);
2323     ASSERT_TRUE(group_callbacks_);
2324     ASSERT_TRUE(app_register_callback);
2325     app_register_callback.Run(gatt_if, GATT_SUCCESS);
2326     Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
2327   }
2328 
TearDown()2329   void TearDown() override {
2330     groups.clear();
2331     UnicastTestNoInit::TearDown();
2332   }
2333 };
2334 
GetTestAddress(uint8_t index)2335 RawAddress GetTestAddress(uint8_t index) {
2336   CHECK_LT(index, UINT8_MAX);
2337   RawAddress result = {{0xC0, 0xDE, 0xC0, 0xDE, 0x00, index}};
2338   return result;
2339 }
2340 
TEST_F(UnicastTest,Initialize)2341 TEST_F(UnicastTest, Initialize) {
2342   ASSERT_NE(LeAudioClient::Get(), nullptr);
2343   ASSERT_TRUE(LeAudioClient::IsLeAudioClientRunning());
2344 }
2345 
TEST_F(UnicastTestNoInit,InitializeNoHal_2_1)2346 TEST_F(UnicastTestNoInit, InitializeNoHal_2_1) {
2347   ASSERT_FALSE(LeAudioClient::IsLeAudioClientRunning());
2348 
2349   // Report False when asked for Audio HAL 2.1 support
2350   ON_CALL(mock_hal_2_1_verifier, Call()).WillByDefault([]() -> bool {
2351     return false;
2352   });
2353 
2354   BtaAppRegisterCallback app_register_callback;
2355   ON_CALL(mock_gatt_interface_, AppRegister(_, _, _))
2356       .WillByDefault(DoAll(SaveArg<0>(&gatt_callback),
2357                            SaveArg<1>(&app_register_callback)));
2358   std::vector<::bluetooth::le_audio::btle_audio_codec_config_t>
2359       framework_encode_preference;
2360 
2361   EXPECT_DEATH(
2362       LeAudioClient::Initialize(
2363           &mock_audio_hal_client_callbacks_,
2364           base::Bind([](MockFunction<void()>* foo) { foo->Call(); },
2365                      &mock_storage_load),
2366           base::Bind([](MockFunction<bool()>* foo) { return foo->Call(); },
2367                      &mock_hal_2_1_verifier),
2368           framework_encode_preference),
2369       ", LE Audio Client requires Bluetooth Audio HAL V2.1 at least. Either "
2370       "disable LE Audio Profile, or update your HAL");
2371 }
2372 
TEST_F(UnicastTest,ConnectOneEarbudEmpty)2373 TEST_F(UnicastTest, ConnectOneEarbudEmpty) {
2374   const RawAddress test_address0 = GetTestAddress(0);
2375   SetSampleDatabaseEmpty(1, test_address0);
2376   EXPECT_CALL(mock_audio_hal_client_callbacks_,
2377               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
2378       .Times(1);
2379   EXPECT_CALL(mock_gatt_interface_, Close(_)).Times(1);
2380   ConnectLeAudio(test_address0);
2381 }
2382 
TEST_F(UnicastTest,ConnectOneEarbudNoPacs)2383 TEST_F(UnicastTest, ConnectOneEarbudNoPacs) {
2384   const RawAddress test_address0 = GetTestAddress(0);
2385   SetSampleDatabaseEarbudsValid(
2386       1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
2387       codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
2388       default_channel_cnt, 0x0004,
2389       /* source sample freq 16khz */ true, /*add_csis*/
2390       true,                                /*add_cas*/
2391       false,                               /*add_pacs*/
2392       default_ase_cnt /*add_ascs*/);
2393   EXPECT_CALL(mock_audio_hal_client_callbacks_,
2394               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
2395       .Times(1);
2396   EXPECT_CALL(mock_gatt_interface_, Close(_)).Times(1);
2397   ConnectLeAudio(test_address0);
2398 }
2399 
TEST_F(UnicastTest,ConnectOneEarbudNoAscs)2400 TEST_F(UnicastTest, ConnectOneEarbudNoAscs) {
2401   const RawAddress test_address0 = GetTestAddress(0);
2402   SetSampleDatabaseEarbudsValid(
2403       1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
2404       codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
2405       default_channel_cnt, 0x0004,
2406       /* source sample freq 16khz */ true, /*add_csis*/
2407       true,                                /*add_cas*/
2408       true,                                /*add_pacs*/
2409       0 /*add_ascs*/);
2410   EXPECT_CALL(mock_audio_hal_client_callbacks_,
2411               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
2412       .Times(1);
2413   EXPECT_CALL(mock_gatt_interface_, Close(_)).Times(1);
2414   ConnectLeAudio(test_address0);
2415 }
2416 
TEST_F(UnicastTest,ConnectOneEarbudNoCas)2417 TEST_F(UnicastTest, ConnectOneEarbudNoCas) {
2418   const RawAddress test_address0 = GetTestAddress(0);
2419   uint16_t conn_id = 1;
2420   SetSampleDatabaseEarbudsValid(
2421       conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo,
2422       codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
2423       default_channel_cnt, 0x0004,
2424       /* source sample freq 16khz */ true, /*add_csis*/
2425       false,                               /*add_cas*/
2426       true,                                /*add_pacs*/
2427       default_ase_cnt /*add_ascs*/);
2428 
2429   EXPECT_CALL(mock_audio_hal_client_callbacks_,
2430               OnConnectionState(ConnectionState::CONNECTED, test_address0))
2431       .Times(1);
2432   ConnectLeAudio(test_address0);
2433 }
2434 
TEST_F(UnicastTest,ConnectOneEarbudNoCsis)2435 TEST_F(UnicastTest, ConnectOneEarbudNoCsis) {
2436   const RawAddress test_address0 = GetTestAddress(0);
2437   SetSampleDatabaseEarbudsValid(
2438       1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
2439       codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
2440       default_channel_cnt, 0x0004,
2441       /* source sample freq 16khz */ false, /*add_csis*/
2442       true,                                 /*add_cas*/
2443       true,                                 /*add_pacs*/
2444       default_ase_cnt /*add_ascs*/);
2445   EXPECT_CALL(mock_audio_hal_client_callbacks_,
2446               OnConnectionState(ConnectionState::CONNECTED, test_address0))
2447       .Times(1);
2448   ConnectLeAudio(test_address0);
2449 }
2450 
TEST_F(UnicastTest,ConnectDisconnectOneEarbud)2451 TEST_F(UnicastTest, ConnectDisconnectOneEarbud) {
2452   const RawAddress test_address0 = GetTestAddress(0);
2453   SetSampleDatabaseEarbudsValid(1, test_address0,
2454                                 codec_spec_conf::kLeAudioLocationStereo,
2455                                 codec_spec_conf::kLeAudioLocationStereo);
2456   EXPECT_CALL(mock_audio_hal_client_callbacks_,
2457               OnConnectionState(ConnectionState::CONNECTED, test_address0))
2458       .Times(1);
2459   ConnectLeAudio(test_address0);
2460   DisconnectLeAudio(test_address0, 1);
2461 }
2462 
2463 /* same as above case except the disconnect is initiated by remote */
TEST_F(UnicastTest,ConnectRemoteDisconnectOneEarbud)2464 TEST_F(UnicastTest, ConnectRemoteDisconnectOneEarbud) {
2465   const RawAddress test_address0 = GetTestAddress(0);
2466   SetSampleDatabaseEarbudsValid(1, test_address0,
2467                                 codec_spec_conf::kLeAudioLocationStereo,
2468                                 codec_spec_conf::kLeAudioLocationStereo);
2469   EXPECT_CALL(mock_audio_hal_client_callbacks_,
2470               OnConnectionState(ConnectionState::CONNECTED, test_address0))
2471       .Times(1);
2472   ConnectLeAudio(test_address0);
2473   EXPECT_CALL(mock_audio_hal_client_callbacks_,
2474               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
2475       .Times(1);
2476   /* For remote disconnection, expect stack to try background re-connect */
2477   EXPECT_CALL(mock_gatt_interface_,
2478               Open(gatt_if, test_address0,
2479                    BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _))
2480       .Times(1);
2481 
2482   EXPECT_CALL(mock_audio_hal_client_callbacks_,
2483               OnConnectionState(ConnectionState::CONNECTED, test_address0))
2484       .Times(1);
2485   InjectDisconnectedEvent(1, GATT_CONN_TERMINATE_PEER_USER);
2486   SyncOnMainLoop();
2487 
2488   /* For background connect, test needs to Inject Connected Event */
2489   InjectConnectedEvent(test_address0, 1);
2490   SyncOnMainLoop();
2491 }
2492 
2493 /* same as above case except the disconnect is initiated by remote */
TEST_F(UnicastTest,ConnectRemoteDisconnectOnTimeoutOneEarbud)2494 TEST_F(UnicastTest, ConnectRemoteDisconnectOnTimeoutOneEarbud) {
2495   const RawAddress test_address0 = GetTestAddress(0);
2496   SetSampleDatabaseEarbudsValid(1, test_address0,
2497                                 codec_spec_conf::kLeAudioLocationStereo,
2498                                 codec_spec_conf::kLeAudioLocationStereo);
2499   EXPECT_CALL(mock_audio_hal_client_callbacks_,
2500               OnConnectionState(ConnectionState::CONNECTED, test_address0))
2501       .Times(1);
2502   ConnectLeAudio(test_address0);
2503   EXPECT_CALL(mock_audio_hal_client_callbacks_,
2504               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
2505       .Times(1);
2506 
2507   /* Remove default action on the direct connect */
2508   ON_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_DIRECT_CONNECTION, _))
2509       .WillByDefault(Return());
2510 
2511   /* For remote disconnection, expect stack to try background re-connect */
2512   EXPECT_CALL(mock_gatt_interface_,
2513               Open(gatt_if, test_address0, BTM_BLE_DIRECT_CONNECTION, _))
2514       .Times(1);
2515 
2516   EXPECT_CALL(mock_audio_hal_client_callbacks_,
2517               OnConnectionState(ConnectionState::CONNECTED, test_address0))
2518       .Times(1);
2519   InjectDisconnectedEvent(1, GATT_CONN_TIMEOUT);
2520   SyncOnMainLoop();
2521 
2522   /* For background connect, test needs to Inject Connected Event */
2523   InjectConnectedEvent(test_address0, 1);
2524   SyncOnMainLoop();
2525 }
2526 
TEST_F(UnicastTest,ConnectTwoEarbudsCsisGrouped)2527 TEST_F(UnicastTest, ConnectTwoEarbudsCsisGrouped) {
2528   uint8_t group_size = 2;
2529   int group_id = 2;
2530 
2531   // Report working CSIS
2532   ON_CALL(mock_csis_client_module_, IsCsisClientRunning())
2533       .WillByDefault(Return(true));
2534 
2535   // First earbud
2536   const RawAddress test_address0 = GetTestAddress(0);
2537   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true))
2538       .Times(1);
2539   ConnectCsisDevice(test_address0, 1 /*conn_id*/,
2540                     codec_spec_conf::kLeAudioLocationFrontLeft,
2541                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size,
2542                     group_id, 1 /* rank*/);
2543 
2544   // Second earbud
2545   const RawAddress test_address1 = GetTestAddress(1);
2546   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true))
2547       .Times(1);
2548   ConnectCsisDevice(test_address1, 2 /*conn_id*/,
2549                     codec_spec_conf::kLeAudioLocationFrontRight,
2550                     codec_spec_conf::kLeAudioLocationFrontRight, group_size,
2551                     group_id, 2 /* rank*/, true /*connect_through_csis*/);
2552 
2553   Mock::VerifyAndClearExpectations(&mock_btif_storage_);
2554 
2555   /* for Target announcements AutoConnect is always there, until
2556    * device is removed
2557    */
2558   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, false))
2559       .Times(0);
2560   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, false))
2561       .Times(0);
2562 
2563   // Verify grouping information
2564   std::vector<RawAddress> devs =
2565       LeAudioClient::Get()->GetGroupDevices(group_id);
2566   ASSERT_NE(std::find(devs.begin(), devs.end(), test_address0), devs.end());
2567   ASSERT_NE(std::find(devs.begin(), devs.end(), test_address1), devs.end());
2568 
2569   DisconnectLeAudio(test_address0, 1);
2570   DisconnectLeAudio(test_address1, 2);
2571 }
2572 
TEST_F(UnicastTest,ConnectTwoEarbudsCsisGroupUnknownAtConnect)2573 TEST_F(UnicastTest, ConnectTwoEarbudsCsisGroupUnknownAtConnect) {
2574   uint8_t group_size = 2;
2575   uint8_t group_id = 2;
2576 
2577   // Report working CSIS
2578   ON_CALL(mock_csis_client_module_, IsCsisClientRunning())
2579       .WillByDefault(Return(true));
2580 
2581   // First earbud connects without known grouping
2582   const RawAddress test_address0 = GetTestAddress(0);
2583   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true))
2584       .Times(1);
2585   ConnectCsisDevice(test_address0, 1 /*conn_id*/,
2586                     codec_spec_conf::kLeAudioLocationFrontLeft,
2587                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size,
2588                     group_id, 1 /* rank*/);
2589 
2590   // Second earbud
2591   const RawAddress test_address1 = GetTestAddress(1);
2592   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true))
2593       .Times(1);
2594   ConnectCsisDevice(test_address1, 2 /*conn_id*/,
2595                     codec_spec_conf::kLeAudioLocationFrontRight,
2596                     codec_spec_conf::kLeAudioLocationFrontRight, group_size,
2597                     group_id, 2 /* rank*/, true /*connect_through_csis*/);
2598 
2599   Mock::VerifyAndClearExpectations(&mock_btif_storage_);
2600 
2601   // Verify grouping information
2602   std::vector<RawAddress> devs =
2603       LeAudioClient::Get()->GetGroupDevices(group_id);
2604   ASSERT_NE(std::find(devs.begin(), devs.end(), test_address0), devs.end());
2605   ASSERT_NE(std::find(devs.begin(), devs.end(), test_address1), devs.end());
2606 
2607   /* for Target announcements AutoConnect is always there, until
2608    *  device is removed
2609    */
2610   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, false))
2611       .Times(0);
2612   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, false))
2613       .Times(0);
2614   DisconnectLeAudio(test_address0, 1);
2615   DisconnectLeAudio(test_address1, 2);
2616 }
2617 
TEST_F(UnicastTestNoInit,LoadStoredEarbudsCsisGrouped)2618 TEST_F(UnicastTestNoInit, LoadStoredEarbudsCsisGrouped) {
2619   // Prepare two devices
2620   uint8_t group_size = 2;
2621   uint8_t group_id = 2;
2622 
2623   /* Prepare  mock to not inject connect event so the device can stay in
2624    * CONNECTING state*/
2625   ON_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_DIRECT_CONNECTION, false))
2626       .WillByDefault(DoAll(Return()));
2627 
2628   const RawAddress test_address0 = GetTestAddress(0);
2629   SetSampleDatabaseEarbudsValid(
2630       1, test_address0, codec_spec_conf::kLeAudioLocationFrontLeft,
2631       codec_spec_conf::kLeAudioLocationFrontLeft, default_channel_cnt,
2632       default_channel_cnt, 0x0004,
2633       /* source sample freq 16khz */ true, /*add_csis*/
2634       true,                                /*add_cas*/
2635       true,                                /*add_pacs*/
2636       default_ase_cnt,                     /*add_ascs_cnt*/
2637       group_size, 1);
2638 
2639   const RawAddress test_address1 = GetTestAddress(1);
2640   SetSampleDatabaseEarbudsValid(
2641       2, test_address1, codec_spec_conf::kLeAudioLocationFrontRight,
2642       codec_spec_conf::kLeAudioLocationFrontRight, default_channel_cnt,
2643       default_channel_cnt, 0x0004,
2644       /* source sample freq 16khz */ true, /*add_csis*/
2645       true,                                /*add_cas*/
2646       true,                                /*add_pacs*/
2647       default_ase_cnt,                     /*add_ascs_cnt*/
2648       group_size, 2);
2649 
2650   // Load devices from the storage when storage API is called
2651   bool autoconnect = true;
2652 
2653   /* Common storage values */
2654   std::vector<uint8_t> handles;
2655   LeAudioClient::GetHandlesForStorage(test_address0, handles);
2656 
2657   std::vector<uint8_t> ases;
2658   LeAudioClient::GetAsesForStorage(test_address0, ases);
2659 
2660   std::vector<uint8_t> src_pacs;
2661   LeAudioClient::GetSourcePacsForStorage(test_address0, src_pacs);
2662 
2663   std::vector<uint8_t> snk_pacs;
2664   LeAudioClient::GetSinkPacsForStorage(test_address0, snk_pacs);
2665 
2666   EXPECT_CALL(mock_storage_load, Call()).WillOnce([&]() {
2667     do_in_main_thread(
2668         FROM_HERE,
2669         base::Bind(&LeAudioClient::AddFromStorage, test_address0, autoconnect,
2670                    codec_spec_conf::kLeAudioLocationFrontLeft,
2671                    codec_spec_conf::kLeAudioLocationFrontLeft, 0xff, 0xff,
2672                    std::move(handles), std::move(snk_pacs), std::move(src_pacs),
2673                    std::move(ases)));
2674     do_in_main_thread(
2675         FROM_HERE,
2676         base::Bind(&LeAudioClient::AddFromStorage, test_address1, autoconnect,
2677                    codec_spec_conf::kLeAudioLocationFrontRight,
2678                    codec_spec_conf::kLeAudioLocationFrontRight, 0xff, 0xff,
2679                    std::move(handles), std::move(snk_pacs), std::move(src_pacs),
2680                    std::move(ases)));
2681   });
2682 
2683   // Expect stored device0 to connect automatically (first directed connection )
2684   EXPECT_CALL(mock_gatt_interface_,
2685               Open(gatt_if, test_address0, BTM_BLE_DIRECT_CONNECTION, _))
2686       .Times(1);
2687 
2688   // Expect stored device1 to connect automatically (first direct connection)
2689   EXPECT_CALL(mock_gatt_interface_,
2690               Open(gatt_if, test_address1, BTM_BLE_DIRECT_CONNECTION, _))
2691       .Times(1);
2692 
2693   ON_CALL(mock_btm_interface_, BTM_IsEncrypted(test_address1, _))
2694       .WillByDefault(DoAll(Return(true)));
2695   ON_CALL(mock_btm_interface_, BTM_IsEncrypted(test_address0, _))
2696       .WillByDefault(DoAll(Return(true)));
2697 
2698   ON_CALL(mock_groups_module_, GetGroupId(_, _))
2699       .WillByDefault(DoAll(Return(group_id)));
2700 
2701   ON_CALL(mock_btm_interface_,
2702           GetSecurityFlagsByTransport(test_address0, NotNull(), _))
2703       .WillByDefault(
2704           DoAll(SetArgPointee<1>(BTM_SEC_FLAG_ENCRYPTED), Return(true)));
2705 
2706   std::vector<::bluetooth::le_audio::btle_audio_codec_config_t>
2707       framework_encode_preference;
2708 
2709   // Initialize
2710   BtaAppRegisterCallback app_register_callback;
2711   ON_CALL(mock_gatt_interface_, AppRegister(_, _, _))
2712       .WillByDefault(DoAll(SaveArg<0>(&gatt_callback),
2713                            SaveArg<1>(&app_register_callback)));
2714   LeAudioClient::Initialize(
2715       &mock_audio_hal_client_callbacks_,
2716       base::Bind([](MockFunction<void()>* foo) { foo->Call(); },
2717                  &mock_storage_load),
2718       base::Bind([](MockFunction<bool()>* foo) { return foo->Call(); },
2719                  &mock_hal_2_1_verifier),
2720       framework_encode_preference);
2721   if (app_register_callback) app_register_callback.Run(gatt_if, GATT_SUCCESS);
2722 
2723   // We need to wait for the storage callback before verifying stuff
2724   SyncOnMainLoop();
2725   ASSERT_TRUE(LeAudioClient::IsLeAudioClientRunning());
2726   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
2727 
2728   // Simulate devices are not there and phone fallbacks to targeted
2729   // announcements
2730   EXPECT_CALL(mock_gatt_interface_,
2731               Open(gatt_if, test_address0,
2732                    BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _))
2733       .Times(1);
2734 
2735   EXPECT_CALL(mock_gatt_interface_,
2736               Open(gatt_if, test_address1,
2737                    BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _))
2738       .Times(1);
2739 
2740   // Devices not found
2741   InjectConnectedEvent(test_address0, 0, GATT_ERROR);
2742   InjectConnectedEvent(test_address1, 0, GATT_ERROR);
2743 
2744   SyncOnMainLoop();
2745   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
2746 
2747   EXPECT_CALL(mock_audio_hal_client_callbacks_,
2748               OnConnectionState(ConnectionState::CONNECTED, test_address0))
2749       .Times(1);
2750 
2751   EXPECT_CALL(mock_audio_hal_client_callbacks_,
2752               OnConnectionState(ConnectionState::CONNECTED, test_address1))
2753       .Times(1);
2754 
2755   /* For background connect, test needs to Inject Connected Event */
2756   InjectConnectedEvent(test_address0, 1);
2757   InjectConnectedEvent(test_address1, 2);
2758 
2759   // Verify if all went well and we got the proper group
2760   std::vector<RawAddress> devs =
2761       LeAudioClient::Get()->GetGroupDevices(group_id);
2762   ASSERT_NE(std::find(devs.begin(), devs.end(), test_address0), devs.end());
2763   ASSERT_NE(std::find(devs.begin(), devs.end(), test_address1), devs.end());
2764 
2765   DisconnectLeAudio(test_address0, 1);
2766   DisconnectLeAudio(test_address1, 2);
2767 }
2768 
TEST_F(UnicastTestNoInit,LoadStoredEarbudsCsisGroupedDifferently)2769 TEST_F(UnicastTestNoInit, LoadStoredEarbudsCsisGroupedDifferently) {
2770   // Prepare two devices
2771   uint8_t group_size = 1;
2772 
2773   // Device 0
2774   uint8_t group_id0 = 2;
2775   bool autoconnect0 = true;
2776   const RawAddress test_address0 = GetTestAddress(0);
2777   SetSampleDatabaseEarbudsValid(
2778       1, test_address0, codec_spec_conf::kLeAudioLocationFrontLeft,
2779       codec_spec_conf::kLeAudioLocationFrontLeft, 0x0004,
2780       /* source sample freq 16khz */ true, /*add_csis*/
2781       true,                                /*add_cas*/
2782       true,                                /*add_pacs*/
2783       true,                                /*add_ascs*/
2784       group_size, 1);
2785 
2786   ON_CALL(mock_groups_module_, GetGroupId(test_address0, _))
2787       .WillByDefault(DoAll(Return(group_id0)));
2788 
2789   // Device 1
2790   uint8_t group_id1 = 3;
2791   bool autoconnect1 = false;
2792   const RawAddress test_address1 = GetTestAddress(1);
2793   SetSampleDatabaseEarbudsValid(
2794       2, test_address1, codec_spec_conf::kLeAudioLocationFrontRight,
2795       codec_spec_conf::kLeAudioLocationFrontRight, default_channel_cnt,
2796       default_channel_cnt, 0x0004,
2797       /* source sample freq 16khz */ true, /*add_csis*/
2798       true,                                /*add_cas*/
2799       true,                                /*add_pacs*/
2800       default_ase_cnt,                     /*add_ascs_cnt*/
2801       group_size, 2);
2802 
2803   ON_CALL(mock_groups_module_, GetGroupId(test_address1, _))
2804       .WillByDefault(DoAll(Return(group_id1)));
2805 
2806   /* Commont storage values */
2807   std::vector<uint8_t> handles;
2808   LeAudioClient::GetHandlesForStorage(test_address0, handles);
2809 
2810   std::vector<uint8_t> ases;
2811   LeAudioClient::GetAsesForStorage(test_address0, ases);
2812 
2813   std::vector<uint8_t> src_pacs;
2814   LeAudioClient::GetSourcePacsForStorage(test_address0, src_pacs);
2815 
2816   std::vector<uint8_t> snk_pacs;
2817   LeAudioClient::GetSinkPacsForStorage(test_address0, snk_pacs);
2818 
2819   // Load devices from the storage when storage API is called
2820   EXPECT_CALL(mock_storage_load, Call()).WillOnce([&]() {
2821     do_in_main_thread(
2822         FROM_HERE,
2823         base::Bind(&LeAudioClient::AddFromStorage, test_address0, autoconnect0,
2824                    codec_spec_conf::kLeAudioLocationFrontLeft,
2825                    codec_spec_conf::kLeAudioLocationFrontLeft, 0xff, 0xff,
2826                    std::move(handles), std::move(snk_pacs), std::move(src_pacs),
2827                    std::move(ases)));
2828     do_in_main_thread(
2829         FROM_HERE,
2830         base::Bind(&LeAudioClient::AddFromStorage, test_address1, autoconnect1,
2831                    codec_spec_conf::kLeAudioLocationFrontRight,
2832                    codec_spec_conf::kLeAudioLocationFrontRight, 0xff, 0xff,
2833                    std::move(handles), std::move(snk_pacs), std::move(src_pacs),
2834                    std::move(ases)));
2835   });
2836 
2837   // Expect stored device0 to connect automatically
2838   EXPECT_CALL(mock_audio_hal_client_callbacks_,
2839               OnConnectionState(ConnectionState::CONNECTED, test_address0))
2840       .Times(1);
2841   ON_CALL(mock_btm_interface_, BTM_IsEncrypted(test_address0, _))
2842       .WillByDefault(DoAll(Return(true)));
2843   EXPECT_CALL(mock_gatt_interface_,
2844               Open(gatt_if, test_address0, BTM_BLE_DIRECT_CONNECTION, _))
2845       .Times(1);
2846 
2847   // Expect stored device1 to NOT connect automatically
2848   EXPECT_CALL(mock_audio_hal_client_callbacks_,
2849               OnConnectionState(ConnectionState::CONNECTED, test_address1))
2850       .Times(0);
2851   ON_CALL(mock_btm_interface_, BTM_IsEncrypted(test_address1, _))
2852       .WillByDefault(DoAll(Return(true)));
2853   EXPECT_CALL(mock_gatt_interface_,
2854               Open(gatt_if, test_address1, BTM_BLE_DIRECT_CONNECTION, _))
2855       .Times(0);
2856 
2857   // Initialize
2858   BtaAppRegisterCallback app_register_callback;
2859   ON_CALL(mock_gatt_interface_, AppRegister(_, _, _))
2860       .WillByDefault(DoAll(SaveArg<0>(&gatt_callback),
2861                            SaveArg<1>(&app_register_callback)));
2862   std::vector<::bluetooth::le_audio::btle_audio_codec_config_t>
2863       framework_encode_preference;
2864   LeAudioClient::Initialize(
2865       &mock_audio_hal_client_callbacks_,
2866       base::Bind([](MockFunction<void()>* foo) { foo->Call(); },
2867                  &mock_storage_load),
2868       base::Bind([](MockFunction<bool()>* foo) { return foo->Call(); },
2869                  &mock_hal_2_1_verifier),
2870       framework_encode_preference);
2871   if (app_register_callback) app_register_callback.Run(gatt_if, GATT_SUCCESS);
2872 
2873   // We need to wait for the storage callback before verifying stuff
2874   SyncOnMainLoop();
2875   ASSERT_TRUE(LeAudioClient::IsLeAudioClientRunning());
2876   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
2877 
2878   // Simulate device is not there and phone fallbacks to targeted announcements
2879   EXPECT_CALL(mock_gatt_interface_,
2880               Open(gatt_if, test_address0,
2881                    BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _))
2882       .Times(1);
2883 
2884   // Devices not found
2885   InjectConnectedEvent(test_address0, 0, GATT_ERROR);
2886 
2887   SyncOnMainLoop();
2888   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
2889 
2890   /* For background connect, test needs to Inject Connected Event */
2891   InjectConnectedEvent(test_address0, 1);
2892 
2893   // We need to wait for the storage callback before verifying stuff
2894   SyncOnMainLoop();
2895   ASSERT_TRUE(LeAudioClient::IsLeAudioClientRunning());
2896 
2897   std::vector<RawAddress> devs =
2898       LeAudioClient::Get()->GetGroupDevices(group_id0);
2899   ASSERT_NE(std::find(devs.begin(), devs.end(), test_address0), devs.end());
2900   ASSERT_EQ(std::find(devs.begin(), devs.end(), test_address1), devs.end());
2901 
2902   devs = LeAudioClient::Get()->GetGroupDevices(group_id1);
2903   ASSERT_EQ(std::find(devs.begin(), devs.end(), test_address0), devs.end());
2904   ASSERT_NE(std::find(devs.begin(), devs.end(), test_address1), devs.end());
2905 
2906   DisconnectLeAudio(test_address0, 1);
2907 }
2908 
TEST_F(UnicastTest,GroupingAddRemove)2909 TEST_F(UnicastTest, GroupingAddRemove) {
2910   // Earbud connects without known grouping
2911   uint8_t group_id0 = bluetooth::groups::kGroupUnknown;
2912   const RawAddress test_address0 = GetTestAddress(0);
2913 
2914   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true))
2915       .Times(1);
2916   ConnectNonCsisDevice(test_address0, 1 /*conn_id*/,
2917                        codec_spec_conf::kLeAudioLocationFrontLeft,
2918                        codec_spec_conf::kLeAudioLocationFrontLeft);
2919 
2920   group_id0 = MockDeviceGroups::DeviceGroups::Get()->GetGroupId(test_address0);
2921 
2922   // Earbud connects without known grouping
2923   uint8_t group_id1 = bluetooth::groups::kGroupUnknown;
2924   const RawAddress test_address1 = GetTestAddress(1);
2925   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true))
2926       .Times(1);
2927   ConnectNonCsisDevice(test_address1, 2 /*conn_id*/,
2928                        codec_spec_conf::kLeAudioLocationFrontRight,
2929                        codec_spec_conf::kLeAudioLocationFrontRight);
2930 
2931   group_id1 = MockDeviceGroups::DeviceGroups::Get()->GetGroupId(test_address1);
2932 
2933   Mock::VerifyAndClearExpectations(&mock_btif_storage_);
2934 
2935   // Verify individual groups
2936   ASSERT_NE(group_id0, bluetooth::groups::kGroupUnknown);
2937   ASSERT_NE(group_id1, bluetooth::groups::kGroupUnknown);
2938   ASSERT_NE(group_id0, group_id1);
2939   ASSERT_EQ(LeAudioClient::Get()->GetGroupDevices(group_id0).size(), 1u);
2940   ASSERT_EQ(LeAudioClient::Get()->GetGroupDevices(group_id1).size(), 1u);
2941 
2942   // Expectations on reassigning second earbud to the first group
2943   int dev1_storage_group = bluetooth::groups::kGroupUnknown;
2944   int dev1_new_group = bluetooth::groups::kGroupUnknown;
2945 
2946   EXPECT_CALL(
2947       mock_audio_hal_client_callbacks_,
2948       OnGroupNodeStatus(test_address1, group_id1, GroupNodeStatus::REMOVED))
2949       .Times(AtLeast(1));
2950   EXPECT_CALL(mock_audio_hal_client_callbacks_,
2951               OnGroupNodeStatus(test_address1, _, GroupNodeStatus::ADDED))
2952       .WillRepeatedly(SaveArg<1>(&dev1_new_group));
2953   EXPECT_CALL(mock_groups_module_, RemoveDevice(test_address1, group_id1))
2954       .Times(AtLeast(1));
2955   EXPECT_CALL(mock_groups_module_, AddDevice(test_address1, _, _))
2956       .Times(AnyNumber());
2957 
2958   LeAudioClient::Get()->GroupRemoveNode(group_id1, test_address1);
2959   SyncOnMainLoop();
2960 
2961   Mock::VerifyAndClearExpectations(&mock_groups_module_);
2962   Mock::VerifyAndClearExpectations(&mock_btif_storage_);
2963 
2964   EXPECT_CALL(mock_groups_module_, AddDevice(test_address1, _, group_id0))
2965       .Times(1);
2966 
2967   LeAudioClient::Get()->GroupAddNode(group_id0, test_address1);
2968   SyncOnMainLoop();
2969   Mock::VerifyAndClearExpectations(&mock_groups_module_);
2970 
2971   dev1_storage_group =
2972       MockDeviceGroups::DeviceGroups::Get()->GetGroupId(test_address1);
2973 
2974   // Verify regrouping results
2975   EXPECT_EQ(dev1_new_group, group_id0);
2976   EXPECT_EQ(dev1_new_group, dev1_storage_group);
2977   ASSERT_EQ(LeAudioClient::Get()->GetGroupDevices(group_id1).size(), 0u);
2978   ASSERT_EQ(LeAudioClient::Get()->GetGroupDevices(group_id0).size(), 2u);
2979   std::vector<RawAddress> devs =
2980       LeAudioClient::Get()->GetGroupDevices(group_id0);
2981   ASSERT_NE(std::find(devs.begin(), devs.end(), test_address0), devs.end());
2982   ASSERT_NE(std::find(devs.begin(), devs.end(), test_address1), devs.end());
2983 }
2984 
TEST_F(UnicastTest,RemoveNodeWhileStreaming)2985 TEST_F(UnicastTest, RemoveNodeWhileStreaming) {
2986   const RawAddress test_address0 = GetTestAddress(0);
2987   int group_id = bluetooth::groups::kGroupUnknown;
2988 
2989   SetSampleDatabaseEarbudsValid(
2990       1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
2991       codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
2992       default_channel_cnt, 0x0004,
2993       /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/,
2994       true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
2995       0 /*rank*/);
2996   EXPECT_CALL(mock_audio_hal_client_callbacks_,
2997               OnConnectionState(ConnectionState::CONNECTED, test_address0))
2998       .Times(1);
2999   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3000               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
3001       .WillOnce(DoAll(SaveArg<1>(&group_id)));
3002 
3003   ConnectLeAudio(test_address0);
3004   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
3005 
3006   // Start streaming
3007   constexpr uint8_t cis_count_out = 1;
3008   constexpr uint8_t cis_count_in = 0;
3009 
3010   constexpr int gmcs_ccid = 1;
3011   constexpr int gtbs_ccid = 2;
3012 
3013   // Audio sessions are started only when device gets active
3014   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _)).Times(1);
3015   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _)).Times(1);
3016   LeAudioClient::Get()->SetCcidInformation(gmcs_ccid, 4 /* Media */);
3017   LeAudioClient::Get()->SetCcidInformation(gtbs_ccid, 2 /* Phone */);
3018   LeAudioClient::Get()->GroupSetActive(group_id);
3019 
3020   types::BidirectionalPair<std::vector<uint8_t>> ccids = {.sink = {gmcs_ccid},
3021                                                           .source = {}};
3022   EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, ccids)).Times(1);
3023 
3024   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
3025 
3026   SyncOnMainLoop();
3027   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3028   Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_);
3029   Mock::VerifyAndClearExpectations(&mock_state_machine_);
3030   SyncOnMainLoop();
3031 
3032   // Verify Data transfer on one audio source cis
3033   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
3034 
3035   EXPECT_CALL(mock_groups_module_, RemoveDevice(test_address0, group_id))
3036       .Times(1);
3037   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(1);
3038   EXPECT_CALL(mock_state_machine_, ProcessHciNotifAclDisconnected(_, _))
3039       .Times(0);
3040   EXPECT_CALL(
3041       mock_audio_hal_client_callbacks_,
3042       OnGroupNodeStatus(test_address0, group_id, GroupNodeStatus::REMOVED));
3043   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3044               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
3045       .Times(0);
3046 
3047   LeAudioClient::Get()->GroupRemoveNode(group_id, test_address0);
3048 
3049   SyncOnMainLoop();
3050   Mock::VerifyAndClearExpectations(&mock_groups_module_);
3051   Mock::VerifyAndClearExpectations(&mock_state_machine_);
3052   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3053 }
3054 
TEST_F(UnicastTest,GroupingAddTwiceNoRemove)3055 TEST_F(UnicastTest, GroupingAddTwiceNoRemove) {
3056   // Earbud connects without known grouping
3057   uint8_t group_id0 = bluetooth::groups::kGroupUnknown;
3058   const RawAddress test_address0 = GetTestAddress(0);
3059   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true))
3060       .WillOnce(Return())
3061       .RetiresOnSaturation();
3062   ConnectNonCsisDevice(test_address0, 1 /*conn_id*/,
3063                        codec_spec_conf::kLeAudioLocationFrontLeft,
3064                        codec_spec_conf::kLeAudioLocationFrontLeft);
3065 
3066   group_id0 = MockDeviceGroups::DeviceGroups::Get()->GetGroupId(test_address0);
3067 
3068   // Earbud connects without known grouping
3069   uint8_t group_id1 = bluetooth::groups::kGroupUnknown;
3070   const RawAddress test_address1 = GetTestAddress(1);
3071   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true))
3072       .WillOnce(Return())
3073       .RetiresOnSaturation();
3074   ConnectNonCsisDevice(test_address1, 2 /*conn_id*/,
3075                        codec_spec_conf::kLeAudioLocationFrontRight,
3076                        codec_spec_conf::kLeAudioLocationFrontRight);
3077 
3078   Mock::VerifyAndClearExpectations(&mock_btif_storage_);
3079 
3080   group_id1 = MockDeviceGroups::DeviceGroups::Get()->GetGroupId(test_address1);
3081   // Verify individual groups
3082   ASSERT_NE(group_id0, bluetooth::groups::kGroupUnknown);
3083   ASSERT_NE(group_id1, bluetooth::groups::kGroupUnknown);
3084   ASSERT_NE(group_id0, group_id1);
3085   ASSERT_EQ(LeAudioClient::Get()->GetGroupDevices(group_id0).size(), 1u);
3086   ASSERT_EQ(LeAudioClient::Get()->GetGroupDevices(group_id1).size(), 1u);
3087 
3088   // Expectations on reassigning second earbud to the first group
3089   int dev1_storage_group = bluetooth::groups::kGroupUnknown;
3090   int dev1_new_group = bluetooth::groups::kGroupUnknown;
3091 
3092   EXPECT_CALL(
3093       mock_audio_hal_client_callbacks_,
3094       OnGroupNodeStatus(test_address1, group_id1, GroupNodeStatus::REMOVED))
3095       .Times(AtLeast(1));
3096   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3097               OnGroupNodeStatus(test_address1, _, GroupNodeStatus::ADDED))
3098       .WillRepeatedly(SaveArg<1>(&dev1_new_group));
3099 
3100   // FIXME: We should expect removal with group_id context. No such API exists.
3101   EXPECT_CALL(mock_groups_module_, RemoveDevice(test_address1, group_id1))
3102       .Times(AtLeast(1));
3103   EXPECT_CALL(mock_groups_module_, AddDevice(test_address1, _, _))
3104       .Times(AnyNumber());
3105   EXPECT_CALL(mock_groups_module_, AddDevice(test_address1, _, group_id0))
3106       .Times(1);
3107 
3108   // Regroup device: assign new group without removing it from the first one
3109   LeAudioClient::Get()->GroupAddNode(group_id0, test_address1);
3110   SyncOnMainLoop();
3111   Mock::VerifyAndClearExpectations(&mock_groups_module_);
3112 
3113   dev1_storage_group =
3114       MockDeviceGroups::DeviceGroups::Get()->GetGroupId(test_address1);
3115 
3116   // Verify regrouping results
3117   EXPECT_EQ(dev1_new_group, group_id0);
3118   EXPECT_EQ(dev1_new_group, dev1_storage_group);
3119   ASSERT_EQ(LeAudioClient::Get()->GetGroupDevices(group_id1).size(), 0u);
3120   ASSERT_EQ(LeAudioClient::Get()->GetGroupDevices(group_id0).size(), 2u);
3121   std::vector<RawAddress> devs =
3122       LeAudioClient::Get()->GetGroupDevices(group_id0);
3123   ASSERT_NE(std::find(devs.begin(), devs.end(), test_address0), devs.end());
3124   ASSERT_NE(std::find(devs.begin(), devs.end(), test_address1), devs.end());
3125 }
3126 
TEST_F(UnicastTest,RemoveTwoEarbudsCsisGrouped)3127 TEST_F(UnicastTest, RemoveTwoEarbudsCsisGrouped) {
3128   uint8_t group_size = 2;
3129   int group_id0 = 2;
3130   int group_id1 = 3;
3131 
3132   // Report working CSIS
3133   ON_CALL(mock_csis_client_module_, IsCsisClientRunning())
3134       .WillByDefault(Return(true));
3135 
3136   // First group - First earbud
3137   const RawAddress test_address0 = GetTestAddress(0);
3138   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true))
3139       .Times(1);
3140   ConnectCsisDevice(test_address0, 1 /*conn_id*/,
3141                     codec_spec_conf::kLeAudioLocationFrontLeft,
3142                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size,
3143                     group_id0, 1 /* rank*/);
3144 
3145   // First group - Second earbud
3146   const RawAddress test_address1 = GetTestAddress(1);
3147   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true))
3148       .Times(1);
3149   ConnectCsisDevice(test_address1, 2 /*conn_id*/,
3150                     codec_spec_conf::kLeAudioLocationFrontRight,
3151                     codec_spec_conf::kLeAudioLocationFrontRight, group_size,
3152                     group_id0, 2 /* rank*/, true /*connect_through_csis*/);
3153 
3154   // Second group - First earbud
3155   const RawAddress test_address2 = GetTestAddress(2);
3156   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address2, true))
3157       .Times(1);
3158   ConnectCsisDevice(test_address2, 3 /*conn_id*/,
3159                     codec_spec_conf::kLeAudioLocationFrontLeft,
3160                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size,
3161                     group_id1, 1 /* rank*/);
3162 
3163   // Second group - Second earbud
3164   const RawAddress test_address3 = GetTestAddress(3);
3165   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address3, true))
3166       .Times(1);
3167   ConnectCsisDevice(test_address3, 4 /*conn_id*/,
3168                     codec_spec_conf::kLeAudioLocationFrontRight,
3169                     codec_spec_conf::kLeAudioLocationFrontRight, group_size,
3170                     group_id1, 2 /* rank*/, true /*connect_through_csis*/);
3171 
3172   // First group - verify grouping information
3173   std::vector<RawAddress> group0_devs =
3174       LeAudioClient::Get()->GetGroupDevices(group_id0);
3175   ASSERT_NE(std::find(group0_devs.begin(), group0_devs.end(), test_address0),
3176             group0_devs.end());
3177   ASSERT_NE(std::find(group0_devs.begin(), group0_devs.end(), test_address1),
3178             group0_devs.end());
3179 
3180   // Second group - verify grouping information
3181   std::vector<RawAddress> group1_devs =
3182       LeAudioClient::Get()->GetGroupDevices(group_id1);
3183   ASSERT_NE(std::find(group1_devs.begin(), group1_devs.end(), test_address2),
3184             group1_devs.end());
3185   ASSERT_NE(std::find(group1_devs.begin(), group1_devs.end(), test_address3),
3186             group1_devs.end());
3187   Mock::VerifyAndClearExpectations(&mock_btif_storage_);
3188 
3189   // Expect one of the groups to be dropped and devices to be disconnected
3190   EXPECT_CALL(mock_groups_module_, RemoveDevice(test_address0, group_id0))
3191       .Times(1);
3192   EXPECT_CALL(mock_groups_module_, RemoveDevice(test_address1, group_id0))
3193       .Times(1);
3194   EXPECT_CALL(
3195       mock_audio_hal_client_callbacks_,
3196       OnGroupNodeStatus(test_address0, group_id0, GroupNodeStatus::REMOVED));
3197   EXPECT_CALL(
3198       mock_audio_hal_client_callbacks_,
3199       OnGroupNodeStatus(test_address1, group_id0, GroupNodeStatus::REMOVED));
3200   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3201               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
3202       .Times(1);
3203   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3204               OnConnectionState(ConnectionState::DISCONNECTED, test_address1))
3205       .Times(1);
3206 
3207   // Expect the other groups to be left as is
3208   EXPECT_CALL(mock_audio_hal_client_callbacks_, OnGroupStatus(group_id1, _))
3209       .Times(0);
3210   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3211               OnConnectionState(ConnectionState::DISCONNECTED, test_address2))
3212       .Times(0);
3213   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3214               OnConnectionState(ConnectionState::DISCONNECTED, test_address3))
3215       .Times(0);
3216 
3217   do_in_main_thread(
3218       FROM_HERE, base::Bind(&LeAudioClient::GroupDestroy,
3219                             base::Unretained(LeAudioClient::Get()), group_id0));
3220 
3221   SyncOnMainLoop();
3222   Mock::VerifyAndClearExpectations(&mock_btif_storage_);
3223 }
3224 
TEST_F(UnicastTest,RemoveDeviceWhenConnected)3225 TEST_F(UnicastTest, RemoveDeviceWhenConnected) {
3226   const RawAddress test_address0 = GetTestAddress(0);
3227   int group_id = bluetooth::groups::kGroupUnknown;
3228   uint16_t conn_id = 1;
3229 
3230   SetSampleDatabaseEarbudsValid(
3231       conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3232       codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
3233       default_channel_cnt, 0x0004,
3234       /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/,
3235       true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
3236       0 /*rank*/);
3237   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3238               OnConnectionState(ConnectionState::CONNECTED, test_address0))
3239       .Times(1);
3240   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3241               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
3242       .WillOnce(DoAll(SaveArg<1>(&group_id)));
3243   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true))
3244       .Times(1);
3245   ConnectLeAudio(test_address0);
3246   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
3247 
3248   Mock::VerifyAndClearExpectations(&mock_btif_storage_);
3249   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3250 
3251   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, false))
3252       .Times(1);
3253   EXPECT_CALL(mock_gatt_queue_, Clean(conn_id)).Times(AtLeast(1));
3254   EXPECT_CALL(mock_gatt_interface_, Close(conn_id)).Times(1);
3255 
3256   /*
3257    * StopStream will put calls on main_loop so to keep the correct order
3258    * of operations and to avoid races we put the test command on main_loop as
3259    * well.
3260    */
3261   do_in_main_thread(FROM_HERE, base::BindOnce(
3262                                    [](LeAudioClient* client,
3263                                       const RawAddress& test_address0) {
3264                                      client->RemoveDevice(test_address0);
3265                                    },
3266                                    LeAudioClient::Get(), test_address0));
3267   SyncOnMainLoop();
3268 
3269   Mock::VerifyAndClearExpectations(&mock_btif_storage_);
3270   Mock::VerifyAndClearExpectations(&mock_gatt_queue_);
3271   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
3272 }
3273 
TEST_F(UnicastTest,RemoveDeviceWhenConnecting)3274 TEST_F(UnicastTest, RemoveDeviceWhenConnecting) {
3275   const RawAddress test_address0 = GetTestAddress(0);
3276   uint16_t conn_id = 1;
3277 
3278   /* Prepare  mock to not inject connect event so the device can stay in
3279    * CONNECTING state*/
3280   ON_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_DIRECT_CONNECTION, _))
3281       .WillByDefault(DoAll(Return()));
3282 
3283   SetSampleDatabaseEarbudsValid(
3284       conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3285       codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
3286       default_channel_cnt, 0x0004,
3287       /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/,
3288       true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
3289       0 /*rank*/);
3290   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3291               OnConnectionState(ConnectionState::CONNECTED, test_address0))
3292       .Times(0);
3293   ConnectLeAudio(test_address0);
3294 
3295   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3296 
3297   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, true))
3298       .Times(1);
3299   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, false))
3300       .Times(1);
3301 
3302   /*
3303    * StopStream will put calls on main_loop so to keep the correct order
3304    * of operations and to avoid races we put the test command on main_loop as
3305    * well.
3306    */
3307   do_in_main_thread(FROM_HERE, base::BindOnce(
3308                                    [](LeAudioClient* client,
3309                                       const RawAddress& test_address0) {
3310                                      client->RemoveDevice(test_address0);
3311                                    },
3312                                    LeAudioClient::Get(), test_address0));
3313 
3314   SyncOnMainLoop();
3315 
3316   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
3317 }
3318 
TEST_F(UnicastTest,RemoveDeviceWhenGettingConnectionReady)3319 TEST_F(UnicastTest, RemoveDeviceWhenGettingConnectionReady) {
3320   const RawAddress test_address0 = GetTestAddress(0);
3321   uint16_t conn_id = 1;
3322 
3323   /* Prepare  mock to not inject Service Search Complete*/
3324   ON_CALL(mock_gatt_interface_, ServiceSearchRequest(_, _))
3325       .WillByDefault(DoAll(Return()));
3326 
3327   SetSampleDatabaseEarbudsValid(
3328       conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3329       codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
3330       default_channel_cnt, 0x0004,
3331       /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/,
3332       true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
3333       0 /*rank*/);
3334   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3335               OnConnectionState(ConnectionState::CONNECTED, test_address0))
3336       .Times(0);
3337   ConnectLeAudio(test_address0);
3338 
3339   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3340 
3341   EXPECT_CALL(mock_gatt_queue_, Clean(conn_id)).Times(AtLeast(1));
3342   EXPECT_CALL(mock_gatt_interface_, Close(conn_id)).Times(1);
3343   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, false))
3344       .Times(1);
3345 
3346   /*
3347    * StopStream will put calls on main_loop so to keep the correct order
3348    * of operations and to avoid races we put the test command on main_loop as
3349    * well.
3350    */
3351   do_in_main_thread(FROM_HERE, base::BindOnce(
3352                                    [](LeAudioClient* client,
3353                                       const RawAddress& test_address0) {
3354                                      client->RemoveDevice(test_address0);
3355                                    },
3356                                    LeAudioClient::Get(), test_address0));
3357 
3358   SyncOnMainLoop();
3359 
3360   Mock::VerifyAndClearExpectations(&mock_btif_storage_);
3361   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
3362 }
3363 
TEST_F(UnicastTest,DisconnectDeviceWhenConnected)3364 TEST_F(UnicastTest, DisconnectDeviceWhenConnected) {
3365   const RawAddress test_address0 = GetTestAddress(0);
3366   int group_id = bluetooth::groups::kGroupUnknown;
3367   uint16_t conn_id = 1;
3368 
3369   SetSampleDatabaseEarbudsValid(
3370       conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3371       codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
3372       default_channel_cnt, 0x0004,
3373       /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/,
3374       true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
3375       0 /*rank*/);
3376   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3377               OnConnectionState(ConnectionState::CONNECTED, test_address0))
3378       .Times(1);
3379   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3380               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
3381       .WillOnce(DoAll(SaveArg<1>(&group_id)));
3382   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true))
3383       .Times(1);
3384   ConnectLeAudio(test_address0);
3385   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
3386 
3387   Mock::VerifyAndClearExpectations(&mock_btif_storage_);
3388   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3389 
3390   /* for Target announcements AutoConnect is always there, until
3391    * device is removed
3392    */
3393   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, false))
3394       .Times(0);
3395   EXPECT_CALL(mock_gatt_queue_, Clean(conn_id)).Times(AtLeast(1));
3396   EXPECT_CALL(mock_gatt_interface_, Close(conn_id)).Times(1);
3397 
3398   LeAudioClient::Get()->Disconnect(test_address0);
3399   SyncOnMainLoop();
3400 
3401   Mock::VerifyAndClearExpectations(&mock_btif_storage_);
3402   Mock::VerifyAndClearExpectations(&mock_gatt_queue_);
3403   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
3404 }
3405 
TEST_F(UnicastTest,DisconnectDeviceWhenConnecting)3406 TEST_F(UnicastTest, DisconnectDeviceWhenConnecting) {
3407   const RawAddress test_address0 = GetTestAddress(0);
3408   uint16_t conn_id = 1;
3409 
3410   /* Prepare  mock to not inject connect event so the device can stay in
3411    * CONNECTING state*/
3412   ON_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_DIRECT_CONNECTION, _))
3413       .WillByDefault(DoAll(Return()));
3414 
3415   SetSampleDatabaseEarbudsValid(
3416       conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3417       codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
3418       default_channel_cnt, 0x0004,
3419       /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/,
3420       true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
3421       0 /*rank*/);
3422   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3423               OnConnectionState(ConnectionState::CONNECTED, test_address0))
3424       .Times(0);
3425   ConnectLeAudio(test_address0);
3426 
3427   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3428 
3429   /* Prepare on call mock on Close - to not trigger Inject Disconnection, as it
3430    * is done in default mock.
3431    */
3432   ON_CALL(mock_gatt_interface_, Close(_)).WillByDefault(DoAll(Return()));
3433   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, true))
3434       .Times(1);
3435 
3436   LeAudioClient::Get()->Disconnect(test_address0);
3437 
3438   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
3439 }
3440 
TEST_F(UnicastTest,DisconnectDeviceWhenGettingConnectionReady)3441 TEST_F(UnicastTest, DisconnectDeviceWhenGettingConnectionReady) {
3442   const RawAddress test_address0 = GetTestAddress(0);
3443   uint16_t conn_id = global_conn_id;
3444 
3445   /* Prepare  mock to not inject Service Search Complete*/
3446   ON_CALL(mock_gatt_interface_, ServiceSearchRequest(_, _))
3447       .WillByDefault(DoAll(Return()));
3448 
3449   SetSampleDatabaseEarbudsValid(
3450       conn_id, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3451       codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
3452       default_channel_cnt, 0x0004,
3453       /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/,
3454       true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
3455       0 /*rank*/);
3456   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3457               OnConnectionState(ConnectionState::CONNECTED, test_address0))
3458       .Times(0);
3459   ConnectLeAudio(test_address0);
3460 
3461   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3462 
3463   EXPECT_CALL(mock_gatt_queue_, Clean(conn_id)).Times(AtLeast(1));
3464   EXPECT_CALL(mock_gatt_interface_, Close(conn_id)).Times(1);
3465   EXPECT_CALL(mock_gatt_interface_, CancelOpen(gatt_if, test_address0, false))
3466       .Times(0);
3467 
3468   LeAudioClient::Get()->Disconnect(test_address0);
3469   SyncOnMainLoop();
3470 
3471   Mock::VerifyAndClearExpectations(&mock_gatt_queue_);
3472   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
3473 }
3474 
TEST_F(UnicastTest,RemoveWhileStreaming)3475 TEST_F(UnicastTest, RemoveWhileStreaming) {
3476   const RawAddress test_address0 = GetTestAddress(0);
3477   int group_id = bluetooth::groups::kGroupUnknown;
3478 
3479   SetSampleDatabaseEarbudsValid(
3480       1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3481       codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
3482       default_channel_cnt, 0x0004,
3483       /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/,
3484       true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
3485       0 /*rank*/);
3486   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3487               OnConnectionState(ConnectionState::CONNECTED, test_address0))
3488       .Times(1);
3489   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3490               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
3491       .WillOnce(DoAll(SaveArg<1>(&group_id)));
3492 
3493   ConnectLeAudio(test_address0);
3494   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
3495 
3496   // Start streaming
3497   constexpr uint8_t cis_count_out = 1;
3498   constexpr uint8_t cis_count_in = 0;
3499 
3500   constexpr int gmcs_ccid = 1;
3501   constexpr int gtbs_ccid = 2;
3502 
3503   // Audio sessions are started only when device gets active
3504   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _)).Times(1);
3505   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _)).Times(1);
3506   LeAudioClient::Get()->SetCcidInformation(gmcs_ccid, 4 /* Media */);
3507   LeAudioClient::Get()->SetCcidInformation(gtbs_ccid, 2 /* Phone */);
3508   LeAudioClient::Get()->GroupSetActive(group_id);
3509 
3510   types::BidirectionalPair<std::vector<uint8_t>> ccids = {.sink = {gmcs_ccid},
3511                                                           .source = {}};
3512   EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, ccids)).Times(1);
3513 
3514   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
3515 
3516   SyncOnMainLoop();
3517   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3518   Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_);
3519   Mock::VerifyAndClearExpectations(&mock_state_machine_);
3520   SyncOnMainLoop();
3521 
3522   // Verify Data transfer on one audio source cis
3523   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
3524 
3525   EXPECT_CALL(mock_groups_module_, RemoveDevice(test_address0, group_id))
3526       .Times(1);
3527 
3528   LeAudioDeviceGroup* group = nullptr;
3529   EXPECT_CALL(mock_state_machine_, ProcessHciNotifAclDisconnected(_, _))
3530       .WillOnce(DoAll(SaveArg<0>(&group)));
3531   EXPECT_CALL(
3532       mock_audio_hal_client_callbacks_,
3533       OnGroupNodeStatus(test_address0, group_id, GroupNodeStatus::REMOVED));
3534 
3535   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3536               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
3537       .Times(1);
3538 
3539   /*
3540    * StopStream will put calls on main_loop so to keep the correct order
3541    * of operations and to avoid races we put the test command on main_loop as
3542    * well.
3543    */
3544   do_in_main_thread(FROM_HERE, base::BindOnce(
3545                                    [](LeAudioClient* client,
3546                                       const RawAddress& test_address0) {
3547                                      client->RemoveDevice(test_address0);
3548                                    },
3549                                    LeAudioClient::Get(), test_address0));
3550 
3551   SyncOnMainLoop();
3552   Mock::VerifyAndClearExpectations(&mock_groups_module_);
3553   Mock::VerifyAndClearExpectations(&mock_state_machine_);
3554   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3555 
3556   ASSERT_NE(group, nullptr);
3557 }
3558 
TEST_F(UnicastTest,EarbudsTwsStyleStreaming)3559 TEST_F(UnicastTest, EarbudsTwsStyleStreaming) {
3560   const RawAddress test_address0 = GetTestAddress(0);
3561   int group_id = bluetooth::groups::kGroupUnknown;
3562 
3563   SetSampleDatabaseEarbudsValid(
3564       1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3565       codec_spec_conf::kLeAudioLocationStereo, 0x01, 0x01, 0x0004,
3566       /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/,
3567       true /*add_pacs*/, 2 /*add_ascs_cnt*/, 1 /*set_size*/, 0 /*rank*/);
3568   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3569               OnConnectionState(ConnectionState::CONNECTED, test_address0))
3570       .Times(1);
3571   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3572               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
3573       .WillOnce(DoAll(SaveArg<1>(&group_id)));
3574 
3575   ConnectLeAudio(test_address0);
3576   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
3577 
3578   // Start streaming
3579   uint8_t cis_count_out = 2;
3580   uint8_t cis_count_in = 0;
3581 
3582   // Audio sessions are started only when device gets active
3583   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _)).Times(1);
3584   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _)).Times(1);
3585   LeAudioClient::Get()->GroupSetActive(group_id);
3586 
3587   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
3588 
3589   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3590   Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_);
3591   SyncOnMainLoop();
3592 
3593   // Verify Data transfer on one audio source cis
3594   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
3595 
3596   // Suspend
3597   /*TODO Need a way to verify STOP */
3598   LeAudioClient::Get()->GroupSuspend(group_id);
3599   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3600   Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_);
3601 
3602   // Resume
3603   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
3604   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3605   Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_);
3606 
3607   // Stop
3608   StopStreaming(group_id);
3609   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3610 
3611   // Release
3612   EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop()).Times(1);
3613   EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(1);
3614   EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(1);
3615   LeAudioClient::Get()->GroupSetActive(bluetooth::groups::kGroupUnknown);
3616   Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_);
3617 }
3618 
TEST_F(UnicastTest,SpeakerFailedConversationalStreaming)3619 TEST_F(UnicastTest, SpeakerFailedConversationalStreaming) {
3620   const RawAddress test_address0 = GetTestAddress(0);
3621   int group_id = bluetooth::groups::kGroupUnknown;
3622 
3623   supported_src_context_types_ = 0;
3624   supported_snk_context_types_ = 0x0004;
3625 
3626   SetSampleDatabaseEarbudsValid(
3627       1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3628       0, default_channel_cnt,
3629       default_channel_cnt, 0x0004,
3630       /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/,
3631       true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
3632       0 /*rank*/);
3633   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3634               OnConnectionState(ConnectionState::CONNECTED, test_address0))
3635       .Times(1);
3636   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3637               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
3638       .WillOnce(DoAll(SaveArg<1>(&group_id)));
3639 
3640   ConnectLeAudio(test_address0);
3641   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
3642 
3643   // Audio sessions are started only when device gets active
3644   LeAudioClient::Get()->GroupSetActive(group_id);
3645 
3646   /* Nothing to do - expect no crash */
3647 }
3648 
TEST_F(UnicastTest,SpeakerStreaming)3649 TEST_F(UnicastTest, SpeakerStreaming) {
3650   const RawAddress test_address0 = GetTestAddress(0);
3651   int group_id = bluetooth::groups::kGroupUnknown;
3652 
3653   SetSampleDatabaseEarbudsValid(
3654       1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3655       codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
3656       default_channel_cnt, 0x0004,
3657       /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/,
3658       true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
3659       0 /*rank*/);
3660   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3661               OnConnectionState(ConnectionState::CONNECTED, test_address0))
3662       .Times(1);
3663   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3664               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
3665       .WillOnce(DoAll(SaveArg<1>(&group_id)));
3666 
3667   ConnectLeAudio(test_address0);
3668   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
3669 
3670   // Start streaming
3671   uint8_t cis_count_out = 1;
3672   uint8_t cis_count_in = 0;
3673 
3674   // Audio sessions are started only when device gets active
3675   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _)).Times(1);
3676   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _)).Times(1);
3677   LeAudioClient::Get()->GroupSetActive(group_id);
3678 
3679   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
3680 
3681   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3682   Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_);
3683   SyncOnMainLoop();
3684 
3685   // Verify Data transfer on one audio source cis
3686   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
3687 
3688   // Suspend
3689   /*TODO Need a way to verify STOP */
3690   LeAudioClient::Get()->GroupSuspend(group_id);
3691   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3692   Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_);
3693 
3694   // Resume
3695   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
3696   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3697   Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_);
3698 
3699   // Stop
3700   StopStreaming(group_id);
3701   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3702 
3703   // Release
3704   EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop()).Times(1);
3705   EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(1);
3706   EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(1);
3707   LeAudioClient::Get()->GroupSetActive(bluetooth::groups::kGroupUnknown);
3708   Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_);
3709 }
3710 
TEST_F(UnicastTest,SpeakerStreamingAutonomousRelease)3711 TEST_F(UnicastTest, SpeakerStreamingAutonomousRelease) {
3712   const RawAddress test_address0 = GetTestAddress(0);
3713   int group_id = bluetooth::groups::kGroupUnknown;
3714 
3715   SetSampleDatabaseEarbudsValid(
3716       1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
3717       codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
3718       default_channel_cnt, 0x0004,
3719       /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/,
3720       true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
3721       0 /*rank*/);
3722   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3723               OnConnectionState(ConnectionState::CONNECTED, test_address0))
3724       .Times(1);
3725   EXPECT_CALL(mock_audio_hal_client_callbacks_,
3726               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
3727       .WillOnce(DoAll(SaveArg<1>(&group_id)));
3728 
3729   ConnectLeAudio(test_address0);
3730   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
3731 
3732   // Start streaming
3733   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _)).Times(1);
3734   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _)).Times(1);
3735   LeAudioClient::Get()->GroupSetActive(group_id);
3736 
3737   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
3738 
3739   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3740   Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_);
3741   SyncOnMainLoop();
3742 
3743   // Verify Data transfer on one audio source cis
3744   TestAudioDataTransfer(group_id, 1 /* cis_count_out */, 0 /* cis_count_in */,
3745                         1920);
3746 
3747   // Inject the IDLE state as if an autonomous release happened
3748   auto group = streaming_groups.at(group_id);
3749   ASSERT_NE(group, nullptr);
3750   for (LeAudioDevice* device = group->GetFirstDevice(); device != nullptr;
3751        device = group->GetNextDevice(device)) {
3752     for (auto& ase : device->ases_) {
3753       ase.data_path_state = types::AudioStreamDataPathState::IDLE;
3754       ase.state = types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE;
3755       InjectCisDisconnected(group_id, ase.cis_conn_hdl);
3756     }
3757   }
3758 
3759   // Verify no Data transfer after the autonomous release
3760   TestAudioDataTransfer(group_id, 0 /* cis_count_out */, 0 /* cis_count_in */,
3761                         1920);
3762 }
3763 
TEST_F(UnicastTest,TwoEarbudsStreaming)3764 TEST_F(UnicastTest, TwoEarbudsStreaming) {
3765   uint8_t group_size = 2;
3766   int group_id = 2;
3767 
3768   // Report working CSIS
3769   ON_CALL(mock_csis_client_module_, IsCsisClientRunning())
3770       .WillByDefault(Return(true));
3771 
3772   // First earbud
3773   const RawAddress test_address0 = GetTestAddress(0);
3774   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true))
3775       .Times(1);
3776   ConnectCsisDevice(test_address0, 1 /*conn_id*/,
3777                     codec_spec_conf::kLeAudioLocationFrontLeft,
3778                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size,
3779                     group_id, 1 /* rank*/);
3780 
3781   // Second earbud
3782   const RawAddress test_address1 = GetTestAddress(1);
3783   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true))
3784       .Times(1);
3785   ConnectCsisDevice(test_address1, 2 /*conn_id*/,
3786                     codec_spec_conf::kLeAudioLocationFrontRight,
3787                     codec_spec_conf::kLeAudioLocationFrontRight, group_size,
3788                     group_id, 2 /* rank*/, true /*connect_through_csis*/);
3789 
3790   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
3791       .WillByDefault(Invoke([&](int group_id) { return 2; }));
3792 
3793   // Start streaming
3794   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _)).Times(1);
3795   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _)).Times(1);
3796   LeAudioClient::Get()->GroupSetActive(group_id);
3797   Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_);
3798 
3799   StartStreaming(AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_CONTENT_TYPE_SPEECH,
3800                  group_id);
3801 
3802   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3803   Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_);
3804   SyncOnMainLoop();
3805 
3806   // Verify Data transfer on two peer sinks and one source
3807   uint8_t cis_count_out = 2;
3808   uint8_t cis_count_in = 2;
3809   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 40);
3810 
3811   // Suspend
3812   LeAudioClient::Get()->GroupSuspend(group_id);
3813   SyncOnMainLoop();
3814 
3815   // Resume
3816   StartStreaming(AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_CONTENT_TYPE_SPEECH,
3817                  group_id);
3818   SyncOnMainLoop();
3819   Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_);
3820 
3821   // Verify Data transfer still works
3822   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 40);
3823 
3824   // Stop
3825   StopStreaming(group_id, true);
3826   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3827 
3828   // Release
3829   EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop()).Times(1);
3830   EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(1);
3831   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Stop()).Times(1);
3832   EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(1);
3833   LeAudioClient::Get()->GroupSetActive(bluetooth::groups::kGroupUnknown);
3834   Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_);
3835 }
3836 
TEST_F(UnicastTest,TwoEarbudsStreamingContextSwitchNoReconfigure)3837 TEST_F(UnicastTest, TwoEarbudsStreamingContextSwitchNoReconfigure) {
3838   uint8_t group_size = 2;
3839   int group_id = 2;
3840 
3841   // Report working CSIS
3842   ON_CALL(mock_csis_client_module_, IsCsisClientRunning())
3843       .WillByDefault(Return(true));
3844 
3845   // First earbud
3846   const RawAddress test_address0 = GetTestAddress(0);
3847   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true))
3848       .Times(1);
3849   ConnectCsisDevice(test_address0, 1 /*conn_id*/,
3850                     codec_spec_conf::kLeAudioLocationFrontLeft,
3851                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size,
3852                     group_id, 1 /* rank*/);
3853 
3854   // Second earbud
3855   const RawAddress test_address1 = GetTestAddress(1);
3856   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true))
3857       .Times(1);
3858   ConnectCsisDevice(test_address1, 2 /*conn_id*/,
3859                     codec_spec_conf::kLeAudioLocationFrontRight,
3860                     codec_spec_conf::kLeAudioLocationFrontRight, group_size,
3861                     group_id, 2 /* rank*/, true /*connect_through_csis*/);
3862 
3863   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
3864       .WillByDefault(Invoke([&](int group_id) { return 2; }));
3865 
3866   // Start streaming
3867   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _)).Times(1);
3868   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _)).Times(1);
3869   LeAudioClient::Get()->GroupSetActive(group_id);
3870   SyncOnMainLoop();
3871   Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_);
3872 
3873   // Start streaming with new metadata, but use the existing configuration
3874   types::BidirectionalPair<types::AudioContexts> contexts = {
3875       .sink = types::AudioContexts(types::LeAudioContextType::NOTIFICATIONS),
3876       .source = types::AudioContexts()};
3877   EXPECT_CALL(mock_state_machine_,
3878               StartStream(_, types::LeAudioContextType::MEDIA, contexts, _))
3879       .Times(1);
3880 
3881   StartStreaming(AUDIO_USAGE_NOTIFICATION, AUDIO_CONTENT_TYPE_UNKNOWN,
3882                  group_id);
3883 
3884   SyncOnMainLoop();
3885   Mock::VerifyAndClearExpectations(&mock_state_machine_);
3886   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3887   Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_);
3888 
3889   // Do a metadata content switch to ALERTS but stay on MEDIA configuration
3890   EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(0);
3891   EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop).Times(0);
3892   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start).Times(0);
3893   contexts = {.sink = types::AudioContexts(types::LeAudioContextType::ALERTS),
3894               .source = types::AudioContexts()};
3895   EXPECT_CALL(
3896       mock_state_machine_,
3897       StartStream(_, le_audio::types::LeAudioContextType::MEDIA, contexts, _))
3898       .Times(1);
3899   UpdateMetadata(AUDIO_USAGE_ALARM, AUDIO_CONTENT_TYPE_UNKNOWN);
3900 
3901   SyncOnMainLoop();
3902   Mock::VerifyAndClearExpectations(&mock_state_machine_);
3903   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3904   Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_);
3905 
3906   // Do a metadata content switch to EMERGENCY but stay on MEDIA configuration
3907   EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(0);
3908   EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop).Times(0);
3909   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start).Times(0);
3910 
3911   contexts = {
3912       .sink = types::AudioContexts(types::LeAudioContextType::EMERGENCYALARM),
3913       .source = types::AudioContexts()};
3914   EXPECT_CALL(
3915       mock_state_machine_,
3916       StartStream(_, le_audio::types::LeAudioContextType::MEDIA, contexts, _))
3917       .Times(1);
3918   UpdateMetadata(AUDIO_USAGE_EMERGENCY, AUDIO_CONTENT_TYPE_UNKNOWN);
3919 
3920   SyncOnMainLoop();
3921   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3922   Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_);
3923 
3924   // Do a metadata content switch to INSTRUCTIONAL but stay on MEDIA
3925   // configuration
3926   EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(0);
3927   EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop).Times(0);
3928   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start).Times(0);
3929   contexts = {
3930       .sink = types::AudioContexts(types::LeAudioContextType::INSTRUCTIONAL),
3931       .source = types::AudioContexts()};
3932   EXPECT_CALL(
3933       mock_state_machine_,
3934       StartStream(_, le_audio::types::LeAudioContextType::MEDIA, contexts, _))
3935       .Times(1);
3936   UpdateMetadata(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
3937                  AUDIO_CONTENT_TYPE_UNKNOWN);
3938 
3939   SyncOnMainLoop();
3940   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3941   Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_);
3942 }
3943 
TEST_F(UnicastTest,TwoEarbudsStreamingContextSwitchReconfigure)3944 TEST_F(UnicastTest, TwoEarbudsStreamingContextSwitchReconfigure) {
3945   uint8_t group_size = 2;
3946   int group_id = 2;
3947 
3948   // Report working CSIS
3949   ON_CALL(mock_csis_client_module_, IsCsisClientRunning())
3950       .WillByDefault(Return(true));
3951 
3952   // First earbud
3953   const RawAddress test_address0 = GetTestAddress(0);
3954   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true))
3955       .Times(1);
3956   ConnectCsisDevice(test_address0, 1 /*conn_id*/,
3957                     codec_spec_conf::kLeAudioLocationFrontLeft,
3958                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size,
3959                     group_id, 1 /* rank*/);
3960 
3961   // Second earbud
3962   const RawAddress test_address1 = GetTestAddress(1);
3963   EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true))
3964       .Times(1);
3965   ConnectCsisDevice(test_address1, 2 /*conn_id*/,
3966                     codec_spec_conf::kLeAudioLocationFrontRight,
3967                     codec_spec_conf::kLeAudioLocationFrontRight, group_size,
3968                     group_id, 2 /* rank*/, true /*connect_through_csis*/);
3969 
3970   constexpr int gmcs_ccid = 1;
3971   constexpr int gtbs_ccid = 2;
3972 
3973   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
3974       .WillByDefault(Invoke([&](int group_id) { return 2; }));
3975 
3976   // Start streaming MEDIA
3977   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _)).Times(1);
3978   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _)).Times(1);
3979   LeAudioClient::Get()->SetCcidInformation(gmcs_ccid, 4 /* Media */);
3980   LeAudioClient::Get()->SetCcidInformation(gtbs_ccid, 2 /* Phone */);
3981   LeAudioClient::Get()->GroupSetActive(group_id);
3982 
3983   types::BidirectionalPair<std::vector<uint8_t>> ccids = {.sink = {gmcs_ccid},
3984                                                           .source = {}};
3985   EXPECT_CALL(mock_state_machine_, StartStream(_, _, _, ccids)).Times(1);
3986   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
3987 
3988   SyncOnMainLoop();
3989   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
3990   Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_);
3991 
3992   // Verify Data transfer on two peer sinks
3993   uint8_t cis_count_out = 2;
3994   uint8_t cis_count_in = 0;
3995   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
3996 
3997   // Stop
3998   StopStreaming(group_id);
3999   // simulate suspend timeout passed, alarm executing
4000   fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
4001   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
4002 
4003   // Conversational is a bidirectional scenario so expect GTBS CCID
4004   // in the metadata for both directions. Can be called twice when one
4005   // direction resume after the other and metadata is updated.
4006   ccids = {.sink = {gtbs_ccid}, .source = {gtbs_ccid}};
4007   EXPECT_CALL(
4008       mock_state_machine_,
4009       StartStream(_, types::LeAudioContextType::CONVERSATIONAL, _, ccids))
4010       .Times(AtLeast(1));
4011   StartStreaming(AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_CONTENT_TYPE_SPEECH,
4012                  group_id);
4013 
4014   SyncOnMainLoop();
4015   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
4016   Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_);
4017 
4018   // Verify Data transfer on two peer sinks and one source
4019   cis_count_out = 2;
4020   cis_count_in = 2;
4021   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 40);
4022 }
4023 
TEST_F(UnicastTest,TwoEarbuds2ndLateConnect)4024 TEST_F(UnicastTest, TwoEarbuds2ndLateConnect) {
4025   uint8_t group_size = 2;
4026   int group_id = 2;
4027 
4028   // Report working CSIS
4029   ON_CALL(mock_csis_client_module_, IsCsisClientRunning())
4030       .WillByDefault(Return(true));
4031 
4032   const RawAddress test_address0 = GetTestAddress(0);
4033   const RawAddress test_address1 = GetTestAddress(1);
4034 
4035   // First earbud
4036   ConnectCsisDevice(test_address0, 1 /*conn_id*/,
4037                     codec_spec_conf::kLeAudioLocationFrontLeft,
4038                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size,
4039                     group_id, 1 /* rank*/);
4040 
4041   // Start streaming
4042   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _)).Times(1);
4043   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _)).Times(1);
4044   LeAudioClient::Get()->GroupSetActive(group_id);
4045 
4046   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
4047       .WillByDefault(Invoke([&](int group_id) { return 2; }));
4048 
4049   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
4050 
4051   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
4052   Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_);
4053   SyncOnMainLoop();
4054 
4055   // Expect one iso channel to be fed with data
4056   uint8_t cis_count_out = 1;
4057   uint8_t cis_count_in = 0;
4058   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
4059 
4060   // Second earbud connects during stream
4061   ConnectCsisDevice(test_address1, 2 /*conn_id*/,
4062                     codec_spec_conf::kLeAudioLocationFrontRight,
4063                     codec_spec_conf::kLeAudioLocationFrontRight, group_size,
4064                     group_id, 2 /* rank*/, true /*connect_through_csis*/);
4065 
4066   cis_count_out = 2;
4067   cis_count_in = 0;
4068 
4069   /* The above will trigger reconfiguration. After that Audio Hal action
4070    * is needed to restart the stream */
4071   SinkAudioResume();
4072 
4073   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
4074 }
4075 
TEST_F(UnicastTest,TwoEarbuds2ndDisconnected)4076 TEST_F(UnicastTest, TwoEarbuds2ndDisconnected) {
4077   uint8_t group_size = 2;
4078   int group_id = 2;
4079 
4080   // Report working CSIS
4081   ON_CALL(mock_csis_client_module_, IsCsisClientRunning())
4082       .WillByDefault(Return(true));
4083 
4084   // First earbud
4085   const RawAddress test_address0 = GetTestAddress(0);
4086   ConnectCsisDevice(test_address0, 1 /*conn_id*/,
4087                     codec_spec_conf::kLeAudioLocationFrontLeft,
4088                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size,
4089                     group_id, 1 /* rank*/);
4090 
4091   // Second earbud
4092   const RawAddress test_address1 = GetTestAddress(1);
4093   ConnectCsisDevice(test_address1, 2 /*conn_id*/,
4094                     codec_spec_conf::kLeAudioLocationFrontRight,
4095                     codec_spec_conf::kLeAudioLocationFrontRight, group_size,
4096                     group_id, 2 /* rank*/, true /*connect_through_csis*/);
4097 
4098   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
4099       .WillByDefault(Invoke([&](int group_id) { return 2; }));
4100 
4101   // Audio sessions are started only when device gets active
4102   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _)).Times(1);
4103   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _)).Times(1);
4104   LeAudioClient::Get()->GroupSetActive(group_id);
4105 
4106   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
4107   auto group = streaming_groups.at(group_id);
4108 
4109   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
4110   Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_);
4111   SyncOnMainLoop();
4112   ASSERT_EQ(2, group->NumOfConnected());
4113 
4114   // Expect two iso channels to be fed with data
4115   uint8_t cis_count_out = 2;
4116   uint8_t cis_count_in = 0;
4117   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
4118 
4119   // Disconnect one device and expect the group to keep on streaming
4120   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(0);
4121   auto device = group->GetFirstDevice();
4122   for (auto& ase : device->ases_) {
4123     InjectCisDisconnected(group_id, ase.cis_conn_hdl);
4124   }
4125 
4126   /* It is called twice. Once with BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS,
4127    * and then after delay with BTM_BLE_BKG_CONNECT_ALLOW_LIST
4128    */
4129   EXPECT_CALL(mock_gatt_interface_, Open(_, device->address_, _, false))
4130       .Times(2);
4131 
4132   // Record NumOfConnected when groupStateMachine_ gets notified about the
4133   // disconnection
4134   int num_of_connected = 0;
4135   ON_CALL(mock_state_machine_, ProcessHciNotifAclDisconnected(_, _))
4136       .WillByDefault([&num_of_connected](LeAudioDeviceGroup* group,
4137                                          LeAudioDevice* leAudioDevice) {
4138         num_of_connected = group->NumOfConnected();
4139       });
4140 
4141   auto conn_id = device->conn_id_;
4142   InjectDisconnectedEvent(device->conn_id_, GATT_CONN_TERMINATE_PEER_USER);
4143   SyncOnMainLoop();
4144 
4145   // Make sure the state machine knows about the disconnected device
4146   ASSERT_EQ(1, num_of_connected);
4147 
4148   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
4149 
4150   // Expect one channel ISO Data to be sent
4151   cis_count_out = 1;
4152   cis_count_in = 0;
4153   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
4154 
4155   InjectConnectedEvent(device->address_, conn_id);
4156   SyncOnMainLoop();
4157 
4158   // Expect two iso channels to be fed with data
4159   cis_count_out = 2;
4160   cis_count_in = 0;
4161   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
4162 }
4163 
TEST_F(UnicastTest,TwoEarbudsStreamingProfileDisconnect)4164 TEST_F(UnicastTest, TwoEarbudsStreamingProfileDisconnect) {
4165   uint8_t group_size = 2;
4166   int group_id = 2;
4167 
4168   // Report working CSIS
4169   ON_CALL(mock_csis_client_module_, IsCsisClientRunning())
4170       .WillByDefault(Return(true));
4171 
4172   // First earbud
4173   const RawAddress test_address0 = GetTestAddress(0);
4174   ConnectCsisDevice(test_address0, 1 /*conn_id*/,
4175                     codec_spec_conf::kLeAudioLocationFrontLeft,
4176                     codec_spec_conf::kLeAudioLocationFrontLeft, group_size,
4177                     group_id, 1 /* rank*/);
4178 
4179   // Second earbud
4180   const RawAddress test_address1 = GetTestAddress(1);
4181   ConnectCsisDevice(test_address1, 2 /*conn_id*/,
4182                     codec_spec_conf::kLeAudioLocationFrontRight,
4183                     codec_spec_conf::kLeAudioLocationFrontRight, group_size,
4184                     group_id, 2 /* rank*/, true /*connect_through_csis*/);
4185 
4186   ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id))
4187       .WillByDefault(Invoke([&](int group_id) { return 2; }));
4188 
4189   // Audio sessions are started only when device gets active
4190   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _)).Times(1);
4191   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _)).Times(1);
4192   LeAudioClient::Get()->GroupSetActive(group_id);
4193 
4194   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
4195 
4196   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
4197   Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_);
4198   SyncOnMainLoop();
4199 
4200   // Expect two iso channels to be fed with data
4201   uint8_t cis_count_out = 2;
4202   uint8_t cis_count_in = 0;
4203   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
4204 
4205   EXPECT_CALL(mock_gatt_interface_,
4206               Open(_, _, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _))
4207       .Times(1);
4208   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(1);
4209 
4210   DisconnectLeAudio(test_address0, 1);
4211   SyncOnMainLoop();
4212   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
4213   Mock::VerifyAndClearExpectations(&mock_state_machine_);
4214 
4215   EXPECT_CALL(mock_gatt_interface_,
4216               Open(_, _, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _))
4217       .Times(1);
4218 
4219   DisconnectLeAudio(test_address1, 2);
4220 
4221   SyncOnMainLoop();
4222   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
4223 }
4224 
TEST_F(UnicastTest,EarbudsWithStereoSinkMonoSourceSupporting32kHz)4225 TEST_F(UnicastTest, EarbudsWithStereoSinkMonoSourceSupporting32kHz) {
4226   const RawAddress test_address0 = GetTestAddress(0);
4227   int group_id = 0;
4228   SetSampleDatabaseEarbudsValid(
4229       1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
4230       codec_spec_conf::kLeAudioLocationFrontLeft, default_channel_cnt,
4231       default_channel_cnt, 0x0024,
4232       /* source sample freq 32/16khz */ true, /*add_csis*/
4233       true,                                   /*add_cas*/
4234       true,                                   /*add_pacs*/
4235       default_ase_cnt /*add_ascs_cnt*/);
4236   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4237               OnConnectionState(ConnectionState::CONNECTED, test_address0))
4238       .Times(1);
4239   ConnectLeAudio(test_address0);
4240 
4241   // LeAudioCodecConfiguration received_af_sink_config;
4242   const LeAudioCodecConfiguration expected_af_sink_config = {
4243       .num_channels = 2,
4244       .sample_rate = bluetooth::audio::le_audio::kSampleRate32000,
4245       .bits_per_sample = bluetooth::audio::le_audio::kBitsPerSample16,
4246       .data_interval_us = LeAudioCodecConfiguration::kInterval10000Us,
4247   };
4248 
4249   // Audio sessions are started only when device gets active
4250   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _)).Times(1);
4251   EXPECT_CALL(*mock_le_audio_sink_hal_client_,
4252               Start(expected_af_sink_config, _))
4253       .Times(1);
4254   LeAudioClient::Get()->GroupSetActive(group_id);
4255   SyncOnMainLoop();
4256 }
4257 
TEST_F(UnicastTest,MicrophoneAttachToCurrentMediaScenario)4258 TEST_F(UnicastTest, MicrophoneAttachToCurrentMediaScenario) {
4259   const RawAddress test_address0 = GetTestAddress(0);
4260   int group_id = bluetooth::groups::kGroupUnknown;
4261 
4262   SetSampleDatabaseEarbudsValid(
4263       1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
4264       codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
4265       default_channel_cnt, 0x0024, false /*add_csis*/, true /*add_cas*/,
4266       true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
4267       0 /*rank*/);
4268   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4269               OnConnectionState(ConnectionState::CONNECTED, test_address0))
4270       .Times(1);
4271   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4272               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
4273       .WillOnce(DoAll(SaveArg<1>(&group_id)));
4274 
4275   ConnectLeAudio(test_address0);
4276   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
4277 
4278   // Audio sessions are started only when device gets active
4279   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _)).Times(1);
4280   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _)).Times(1);
4281   LeAudioClient::Get()->GroupSetActive(group_id);
4282 
4283   // When the local audio source resumes we have no knowledge of recording
4284   EXPECT_CALL(mock_state_machine_,
4285               StartStream(_, le_audio::types::LeAudioContextType::MEDIA, _, _))
4286       .Times(1);
4287 
4288   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id,
4289                  AUDIO_SOURCE_INVALID);
4290   SyncOnMainLoop();
4291 
4292   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
4293   Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_);
4294 
4295   // Verify Data transfer on one audio source cis
4296   uint8_t cis_count_out = 1;
4297   uint8_t cis_count_in = 0;
4298   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
4299 
4300   // When the local audio sink resumes we should reconfigure
4301   EXPECT_CALL(
4302       mock_state_machine_,
4303       ConfigureStream(_, le_audio::types::LeAudioContextType::LIVE, _, _))
4304       .Times(1);
4305   EXPECT_CALL(*mock_le_audio_source_hal_client_, ReconfigurationComplete())
4306       .Times(1);
4307 
4308   // Update metadata on local audio sink
4309   UpdateSourceMetadata(AUDIO_SOURCE_MIC);
4310 
4311   // Resume on local audio sink
4312   ASSERT_NE(unicast_sink_hal_cb_, nullptr);
4313   do_in_main_thread(
4314       FROM_HERE,
4315       base::BindOnce(
4316           [](LeAudioSinkAudioHalClient::Callbacks* cb) { cb->OnAudioResume(); },
4317           unicast_sink_hal_cb_));
4318 
4319   /* The above will trigger reconfiguration. After that Audio Hal action
4320    * is needed to restart the stream */
4321   SyncOnMainLoop();
4322 
4323   Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_);
4324   Mock::VerifyAndClearExpectations(&mock_state_machine_);
4325 
4326   SinkAudioResume();
4327   do_in_main_thread(
4328       FROM_HERE,
4329       base::BindOnce(
4330           [](LeAudioSinkAudioHalClient::Callbacks* cb) { cb->OnAudioResume(); },
4331           unicast_sink_hal_cb_));
4332   SyncOnMainLoop();
4333 
4334   // Verify Data transfer on one audio source and sink cis
4335   cis_count_out = 1;
4336   cis_count_in = 1;
4337   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 60);
4338 
4339   // Stop
4340   StopStreaming(group_id);
4341   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
4342 
4343   // Release
4344   EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop()).Times(1);
4345   EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(1);
4346   EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(1);
4347   do_in_main_thread(
4348       FROM_HERE, base::BindOnce(
4349                      [](LeAudioClient* client) {
4350                        client->GroupSetActive(bluetooth::groups::kGroupUnknown);
4351                      },
4352                      LeAudioClient::Get()));
4353   Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_);
4354 
4355   SyncOnMainLoop();
4356 }
4357 
TEST_F(UnicastTest,UpdateNotSupportedContextType)4358 TEST_F(UnicastTest, UpdateNotSupportedContextType) {
4359   const RawAddress test_address0 = GetTestAddress(0);
4360   int group_id = bluetooth::groups::kGroupUnknown;
4361 
4362   supported_snk_context_types_ = (types::LeAudioContextType::RINGTONE |
4363                                   types::LeAudioContextType::CONVERSATIONAL |
4364                                   types::LeAudioContextType::UNSPECIFIED |
4365                                   types::LeAudioContextType::MEDIA)
4366                                      .value();
4367   supported_src_context_types_ = supported_snk_context_types_;
4368 
4369   SetSampleDatabaseEarbudsValid(
4370       1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
4371       codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
4372       default_channel_cnt, 0x0004, false /*add_csis*/, true /*add_cas*/,
4373       true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
4374       0 /*rank*/);
4375   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4376               OnConnectionState(ConnectionState::CONNECTED, test_address0))
4377       .Times(1);
4378   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4379               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
4380       .WillOnce(DoAll(SaveArg<1>(&group_id)));
4381 
4382   ConnectLeAudio(test_address0);
4383   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
4384 
4385   // Start streaming
4386   uint8_t cis_count_out = 1;
4387   uint8_t cis_count_in = 0;
4388 
4389   LeAudioClient::Get()->SetInCall(true);
4390 
4391   // Audio sessions are started only when device gets active
4392   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _)).Times(1);
4393   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _)).Times(1);
4394   LeAudioClient::Get()->GroupSetActive(group_id);
4395 
4396   StartStreaming(AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE,
4397                  AUDIO_CONTENT_TYPE_UNKNOWN, group_id);
4398 
4399   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
4400   Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_);
4401   SyncOnMainLoop();
4402 
4403   // Verify Data transfer on one audio source cis
4404   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
4405 
4406   LeAudioClient::Get()->SetInCall(false);
4407 
4408   /* We should stay on the existing configuration as there is no GAME
4409    * context available on the remote device.
4410    */
4411   EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(0);
4412   types::BidirectionalPair<types::AudioContexts> contexts = {
4413       .sink = types::AudioContexts(types::LeAudioContextType::UNSPECIFIED),
4414       .source = types::AudioContexts(types::LeAudioContextType::UNSPECIFIED)};
4415   EXPECT_CALL(
4416       mock_state_machine_,
4417       StartStream(_, types::LeAudioContextType::CONVERSATIONAL, contexts, _))
4418       .Times(1);
4419   UpdateMetadata(AUDIO_USAGE_GAME, AUDIO_CONTENT_TYPE_UNKNOWN, false);
4420 
4421   /* If the above triggers reconfiguration, Audio Hal action is needed to
4422    * restart the stream.
4423    */
4424   SinkAudioResume();
4425 }
4426 
TEST_F(UnicastTest,StartNotSupportedContextType)4427 TEST_F(UnicastTest, StartNotSupportedContextType) {
4428   const RawAddress test_address0 = GetTestAddress(0);
4429   int group_id = bluetooth::groups::kGroupUnknown;
4430 
4431   supported_snk_context_types_ = (types::LeAudioContextType::RINGTONE |
4432                                   types::LeAudioContextType::CONVERSATIONAL |
4433                                   types::LeAudioContextType::UNSPECIFIED |
4434                                   types::LeAudioContextType::MEDIA)
4435                                      .value();
4436   supported_src_context_types_ = supported_snk_context_types_;
4437 
4438   SetSampleDatabaseEarbudsValid(
4439       1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
4440       codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
4441       default_channel_cnt, 0x0004, false /*add_csis*/, true /*add_cas*/,
4442       true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
4443       0 /*rank*/);
4444   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4445               OnConnectionState(ConnectionState::CONNECTED, test_address0))
4446       .Times(1);
4447   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4448               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
4449       .WillOnce(DoAll(SaveArg<1>(&group_id)));
4450 
4451   ConnectLeAudio(test_address0);
4452   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
4453 
4454   // Expect configuring to the default config since the EMERGENCYALARM is
4455   // not on the list of supported contexts and UNSPECIFIED will be used in
4456   // the metadata.
4457   auto default_config = types::LeAudioContextType::MEDIA;
4458   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _)).Times(1);
4459   types::BidirectionalPair<types::AudioContexts> metadata = {
4460       .sink = types::AudioContexts(types::LeAudioContextType::UNSPECIFIED),
4461       .source = types::AudioContexts(types::LeAudioContextType::UNSPECIFIED)};
4462   EXPECT_CALL(mock_state_machine_, StartStream(_, default_config, metadata, _))
4463       .Times(1);
4464 
4465   LeAudioClient::Get()->GroupSetActive(group_id);
4466 
4467   StartStreaming(AUDIO_USAGE_EMERGENCY, AUDIO_CONTENT_TYPE_UNKNOWN, group_id);
4468 
4469   SyncOnMainLoop();
4470   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
4471   Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_);
4472 
4473   // Verify Data transfer on one audio source cis
4474   uint8_t cis_count_out = 1;
4475   uint8_t cis_count_in = 0;
4476   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
4477 }
4478 
TEST_F(UnicastTest,NotifyAboutGroupTunrnedIdleEnabled)4479 TEST_F(UnicastTest, NotifyAboutGroupTunrnedIdleEnabled) {
4480   const RawAddress test_address0 = GetTestAddress(0);
4481   int group_id = bluetooth::groups::kGroupUnknown;
4482 
4483   osi_property_set_bool(kNotifyUpperLayerAboutGroupBeingInIdleDuringCall, true);
4484 
4485   SetSampleDatabaseEarbudsValid(
4486       1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
4487       codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
4488       default_channel_cnt, 0x0004, false /*add_csis*/, true /*add_cas*/,
4489       true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
4490       0 /*rank*/);
4491   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4492               OnConnectionState(ConnectionState::CONNECTED, test_address0))
4493       .Times(1);
4494   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4495               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
4496       .WillOnce(DoAll(SaveArg<1>(&group_id)));
4497 
4498   ConnectLeAudio(test_address0);
4499   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
4500 
4501   // Start streaming
4502   uint8_t cis_count_out = 1;
4503   uint8_t cis_count_in = 0;
4504 
4505   LeAudioClient::Get()->SetInCall(true);
4506 
4507   // Audio sessions are started only when device gets active
4508   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _)).Times(1);
4509   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _)).Times(1);
4510   LeAudioClient::Get()->GroupSetActive(group_id);
4511 
4512   StartStreaming(AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE,
4513                  AUDIO_CONTENT_TYPE_UNKNOWN, group_id);
4514 
4515   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
4516   Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_);
4517   SyncOnMainLoop();
4518 
4519   // Verify Data transfer on one audio source cis
4520   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
4521 
4522   // Release
4523 
4524   /* To be called twice
4525    * 1. GroupStatus::INACTIVE
4526    * 2. GroupStatus::TURNED_IDLE_DURING_CALL
4527    */
4528   EXPECT_CALL(mock_audio_hal_client_callbacks_, OnGroupStatus(group_id, _))
4529       .Times(2);
4530 
4531   EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop()).Times(1);
4532   EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(1);
4533   EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(1);
4534 
4535   do_in_main_thread(
4536       FROM_HERE, base::BindOnce(
4537                      [](LeAudioClient* client) {
4538                        client->GroupSetActive(bluetooth::groups::kGroupUnknown);
4539                      },
4540                      LeAudioClient::Get()));
4541 
4542   SyncOnMainLoop();
4543   Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_);
4544 
4545   LeAudioClient::Get()->SetInCall(false);
4546   osi_property_set_bool(kNotifyUpperLayerAboutGroupBeingInIdleDuringCall,
4547                         false);
4548 }
4549 
TEST_F(UnicastTest,NotifyAboutGroupTunrnedIdleDisabled)4550 TEST_F(UnicastTest, NotifyAboutGroupTunrnedIdleDisabled) {
4551   const RawAddress test_address0 = GetTestAddress(0);
4552   int group_id = bluetooth::groups::kGroupUnknown;
4553 
4554   SetSampleDatabaseEarbudsValid(
4555       1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
4556       codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
4557       default_channel_cnt, 0x0004, false /*add_csis*/, true /*add_cas*/,
4558       true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
4559       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   // Start streaming
4571   uint8_t cis_count_out = 1;
4572   uint8_t cis_count_in = 0;
4573 
4574   LeAudioClient::Get()->SetInCall(true);
4575 
4576   // Audio sessions are started only when device gets active
4577   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _)).Times(1);
4578   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _)).Times(1);
4579   LeAudioClient::Get()->GroupSetActive(group_id);
4580 
4581   StartStreaming(AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE,
4582                  AUDIO_CONTENT_TYPE_UNKNOWN, group_id);
4583 
4584   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
4585   Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_);
4586   SyncOnMainLoop();
4587 
4588   // Verify Data transfer on one audio source cis
4589   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
4590 
4591   // Release
4592 
4593   /* To be called once only
4594    * 1. GroupStatus::INACTIVE
4595    */
4596   EXPECT_CALL(mock_audio_hal_client_callbacks_, OnGroupStatus(group_id, _))
4597       .Times(1);
4598 
4599   EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop()).Times(1);
4600   EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(1);
4601   EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(1);
4602 
4603   do_in_main_thread(
4604       FROM_HERE, base::BindOnce(
4605                      [](LeAudioClient* client) {
4606                        client->GroupSetActive(bluetooth::groups::kGroupUnknown);
4607                      },
4608                      LeAudioClient::Get()));
4609 
4610   SyncOnMainLoop();
4611   Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_);
4612 
4613   LeAudioClient::Get()->SetInCall(false);
4614 }
4615 
TEST_F(UnicastTest,HandleDatabaseOutOfSync)4616 TEST_F(UnicastTest, HandleDatabaseOutOfSync) {
4617   const RawAddress test_address0 = GetTestAddress(0);
4618   int group_id = bluetooth::groups::kGroupUnknown;
4619 
4620   SetSampleDatabaseEarbudsValid(
4621       1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
4622       codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
4623       default_channel_cnt, 0x0004, false /*add_csis*/, true /*add_cas*/,
4624       true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
4625       0 /*rank*/);
4626   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4627               OnConnectionState(ConnectionState::CONNECTED, test_address0))
4628       .Times(1);
4629   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4630               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
4631       .WillOnce(DoAll(SaveArg<1>(&group_id)));
4632 
4633   ConnectLeAudio(test_address0);
4634   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
4635 
4636   SyncOnMainLoop();
4637   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
4638 
4639   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4640               OnConnectionState(ConnectionState::DISCONNECTED, test_address0))
4641       .Times(1);
4642   InjectDisconnectedEvent(1, GATT_CONN_TERMINATE_PEER_USER);
4643   SyncOnMainLoop();
4644   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
4645 
4646   // default action for WriteDescriptor function call
4647   ON_CALL(mock_gatt_queue_, WriteDescriptor(_, _, _, _, _, _))
4648       .WillByDefault(Invoke([](uint16_t conn_id, uint16_t handle,
4649                                std::vector<uint8_t> value,
4650                                tGATT_WRITE_TYPE write_type, GATT_WRITE_OP_CB cb,
4651                                void* cb_data) -> void {
4652         if (cb)
4653           do_in_main_thread(
4654               FROM_HERE,
4655               base::BindOnce(
4656                   [](GATT_WRITE_OP_CB cb, uint16_t conn_id, uint16_t handle,
4657                      uint16_t len, uint8_t* value, void* cb_data) {
4658                     cb(conn_id, GATT_DATABASE_OUT_OF_SYNC, handle, len, value,
4659                        cb_data);
4660                   },
4661                   cb, conn_id, handle, value.size(), value.data(), cb_data));
4662       }));
4663 
4664   ON_CALL(mock_gatt_interface_, ServiceSearchRequest(_, _))
4665       .WillByDefault(Return());
4666   EXPECT_CALL(mock_gatt_interface_, ServiceSearchRequest(_, _));
4667 
4668   InjectConnectedEvent(test_address0, 1);
4669   SyncOnMainLoop();
4670   Mock::VerifyAndClearExpectations(&mock_gatt_interface_);
4671 }
4672 
TEST_F(UnicastTest,SpeakerStreamingTimeout)4673 TEST_F(UnicastTest, SpeakerStreamingTimeout) {
4674   const RawAddress test_address0 = GetTestAddress(0);
4675   int group_id = bluetooth::groups::kGroupUnknown;
4676 
4677   SetSampleDatabaseEarbudsValid(
4678       1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
4679       codec_spec_conf::kLeAudioLocationStereo, default_channel_cnt,
4680       default_channel_cnt, 0x0004,
4681       /* source sample freq 16khz */ false /*add_csis*/, true /*add_cas*/,
4682       true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
4683       0 /*rank*/);
4684   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4685               OnConnectionState(ConnectionState::CONNECTED, test_address0))
4686       .Times(1);
4687   EXPECT_CALL(mock_audio_hal_client_callbacks_,
4688               OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
4689       .WillOnce(DoAll(SaveArg<1>(&group_id)));
4690 
4691   ConnectLeAudio(test_address0);
4692   ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
4693 
4694   // Start streaming
4695   uint8_t cis_count_out = 1;
4696   uint8_t cis_count_in = 0;
4697 
4698   // Audio sessions are started only when device gets active
4699   EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _)).Times(1);
4700   EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _)).Times(1);
4701   LeAudioClient::Get()->GroupSetActive(group_id);
4702 
4703   StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id);
4704 
4705   Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
4706   Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_);
4707   SyncOnMainLoop();
4708 
4709   // Verify Data transfer on one audio source cis
4710   TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
4711 
4712   // Do not accept direct connect, but expect it to arrive.
4713   ON_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_DIRECT_CONNECTION, _))
4714       .WillByDefault(Return());
4715 
4716   state_machine_callbacks_->OnStateTransitionTimeout(group_id);
4717   SyncOnMainLoop();
4718 
4719   /* No assigned cises should remain when transition remains in IDLE state */
4720   auto group = streaming_groups.at(group_id);
4721   ASSERT_EQ(0, static_cast<int>(group->cises_.size()));
4722 }
4723 }  // namespace le_audio
4724