1 /*
2  * Copyright 2021 HIMSA II K/S - www.himsa.com.
3  * Represented by EHIMA - www.ehima.com
4  * Copyright (c) 2022 The Android Open Source Project
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 #include "audio_hal_client.h"
20 
21 #include <bluetooth/log.h>
22 #include <gmock/gmock.h>
23 #include <gtest/gtest.h>
24 
25 #include <chrono>
26 #include <future>
27 
28 #include "audio_hal_interface/le_audio_software.h"
29 #include "base/bind_helpers.h"
30 #include "common/message_loop_thread.h"
31 #include "hardware/bluetooth.h"
32 #include "osi/include/wakelock.h"
33 
34 // TODO(b/369381361) Enfore -Wmissing-prototypes
35 #pragma GCC diagnostic ignored "-Wmissing-prototypes"
36 
37 using ::testing::_;
38 using ::testing::Assign;
39 using ::testing::AtLeast;
40 using ::testing::DoAll;
41 using ::testing::DoDefault;
42 using ::testing::Invoke;
43 using ::testing::Mock;
44 using ::testing::Return;
45 using ::testing::ReturnPointee;
46 using ::testing::SaveArg;
47 using std::chrono_literals::operator""ms;
48 
49 using bluetooth::le_audio::DsaMode;
50 using bluetooth::le_audio::DsaModes;
51 using bluetooth::le_audio::LeAudioCodecConfiguration;
52 using bluetooth::le_audio::LeAudioSinkAudioHalClient;
53 using bluetooth::le_audio::LeAudioSourceAudioHalClient;
54 
55 using namespace bluetooth;
56 
57 bluetooth::common::MessageLoopThread message_loop_thread("test message loop");
get_main_thread()58 bluetooth::common::MessageLoopThread* get_main_thread() { return &message_loop_thread; }
do_in_main_thread(base::OnceClosure task)59 bt_status_t do_in_main_thread(base::OnceClosure task) {
60   if (!message_loop_thread.DoInThread(FROM_HERE, std::move(task))) {
61     log::error("failed to post task to task runner!");
62     return BT_STATUS_FAIL;
63   }
64   return BT_STATUS_SUCCESS;
65 }
66 
67 static base::MessageLoop* message_loop_;
get_main_message_loop()68 base::MessageLoop* get_main_message_loop() { return message_loop_; }
69 
init_message_loop_thread()70 static void init_message_loop_thread() {
71   message_loop_thread.StartUp();
72   if (!message_loop_thread.IsRunning()) {
73     FAIL() << "unable to create message loop thread.";
74   }
75 
76   if (!message_loop_thread.EnableRealTimeScheduling()) {
77     log::error("Unable to set real time scheduling");
78   }
79 
80   message_loop_ = message_loop_thread.message_loop();
81   if (message_loop_ == nullptr) {
82     FAIL() << "unable to get message loop.";
83   }
84 }
85 
cleanup_message_loop_thread()86 static void cleanup_message_loop_thread() {
87   message_loop_ = nullptr;
88   message_loop_thread.ShutDown();
89 }
90 
91 using bluetooth::audio::le_audio::LeAudioClientInterface;
92 
93 class MockLeAudioClientInterfaceSink : public LeAudioClientInterface::Sink {
94 public:
95   MOCK_METHOD((void), Cleanup, (), (override));
96   MOCK_METHOD((void), SetPcmParameters, (const LeAudioClientInterface::PcmParameters& params),
97               (override));
98   MOCK_METHOD((void), SetRemoteDelay, (uint16_t delay_report_ms), (override));
99   MOCK_METHOD((void), StartSession, (), (override));
100   MOCK_METHOD((void), StopSession, (), (override));
101   MOCK_METHOD((void), ConfirmStreamingRequest, (), (override));
102   MOCK_METHOD((void), CancelStreamingRequest, (), (override));
103   MOCK_METHOD((void), UpdateAudioConfigToHal, (const ::bluetooth::le_audio::offload_config&));
104   MOCK_METHOD((std::optional<::le_audio::broadcaster::BroadcastConfiguration>), GetBroadcastConfig,
105               ((const std::vector<std::pair<::le_audio::types::LeAudioContextType, uint8_t>>&),
106                (const std::optional<std::vector<::bluetooth::le_audio::types::acs_ac_record>>&)),
107               (const));
108   MOCK_METHOD((std::optional<::le_audio::set_configurations::AudioSetConfiguration>),
109               GetUnicastConfig,
110               (const ::bluetooth::le_audio::CodecManager::UnicastConfigurationRequirements&),
111               (const));
112   MOCK_METHOD((void), UpdateBroadcastAudioConfigToHal,
113               (const ::bluetooth::le_audio::broadcast_offload_config&));
114   MOCK_METHOD((size_t), Read, (uint8_t* p_buf, uint32_t len));
115 };
116 
117 class MockLeAudioClientInterfaceSource : public LeAudioClientInterface::Source {
118 public:
119   MOCK_METHOD((void), Cleanup, (), (override));
120   MOCK_METHOD((void), SetPcmParameters, (const LeAudioClientInterface::PcmParameters& params),
121               (override));
122   MOCK_METHOD((void), SetRemoteDelay, (uint16_t delay_report_ms), (override));
123   MOCK_METHOD((void), StartSession, (), (override));
124   MOCK_METHOD((void), StopSession, (), (override));
125   MOCK_METHOD((void), ConfirmStreamingRequest, (), (override));
126   MOCK_METHOD((void), CancelStreamingRequest, (), (override));
127   MOCK_METHOD((void), UpdateAudioConfigToHal, (const ::bluetooth::le_audio::offload_config&));
128   MOCK_METHOD((size_t), Write, (const uint8_t* p_buf, uint32_t len));
129 };
130 
131 class MockLeAudioClientInterface : public LeAudioClientInterface {
132 public:
133   MockLeAudioClientInterface() = default;
134   ~MockLeAudioClientInterface() = default;
135 
136   MOCK_METHOD((Sink*), GetSink,
137               (bluetooth::audio::le_audio::StreamCallbacks stream_cb,
138                bluetooth::common::MessageLoopThread* message_loop,
139                bool is_broadcasting_session_type));
140   MOCK_METHOD((Source*), GetSource,
141               (bluetooth::audio::le_audio::StreamCallbacks stream_cb,
142                bluetooth::common::MessageLoopThread* message_loop));
143 
144   MOCK_METHOD((void), SetAllowedDsaModes, (DsaModes dsa_modes));
145 };
146 
147 LeAudioClientInterface* mockInterface;
148 
149 namespace bluetooth {
150 namespace audio {
151 namespace le_audio {
152 MockLeAudioClientInterface* interface_mock;
153 MockLeAudioClientInterfaceSink* sink_mock;
154 MockLeAudioClientInterfaceSource* source_mock;
155 
Get()156 LeAudioClientInterface* LeAudioClientInterface::Get() { return interface_mock; }
157 
GetSink(StreamCallbacks stream_cb,bluetooth::common::MessageLoopThread * message_loop,bool is_broadcasting_session_type)158 LeAudioClientInterface::Sink* LeAudioClientInterface::GetSink(
159         StreamCallbacks stream_cb, bluetooth::common::MessageLoopThread* message_loop,
160         bool is_broadcasting_session_type) {
161   return interface_mock->GetSink(stream_cb, message_loop, is_broadcasting_session_type);
162 }
163 
GetSource(StreamCallbacks stream_cb,bluetooth::common::MessageLoopThread * message_loop)164 LeAudioClientInterface::Source* LeAudioClientInterface::GetSource(
165         StreamCallbacks stream_cb, bluetooth::common::MessageLoopThread* message_loop) {
166   return interface_mock->GetSource(stream_cb, message_loop);
167 }
168 
ReleaseSink(LeAudioClientInterface::Sink *)169 bool LeAudioClientInterface::ReleaseSink(LeAudioClientInterface::Sink* /*sink*/) { return true; }
ReleaseSource(LeAudioClientInterface::Source *)170 bool LeAudioClientInterface::ReleaseSource(LeAudioClientInterface::Source* /*source*/) {
171   return true;
172 }
173 
SetAllowedDsaModes(DsaModes)174 void LeAudioClientInterface::SetAllowedDsaModes(DsaModes /*dsa_modes*/) { return; }
175 
Cleanup()176 void LeAudioClientInterface::Sink::Cleanup() {}
SetPcmParameters(const PcmParameters &)177 void LeAudioClientInterface::Sink::SetPcmParameters(const PcmParameters& /*params*/) {}
SetRemoteDelay(uint16_t)178 void LeAudioClientInterface::Sink::SetRemoteDelay(uint16_t /*delay_report_ms*/) {}
StartSession()179 void LeAudioClientInterface::Sink::StartSession() {}
StopSession()180 void LeAudioClientInterface::Sink::StopSession() {}
ConfirmStreamingRequest()181 void LeAudioClientInterface::Sink::ConfirmStreamingRequest() {}
CancelStreamingRequest()182 void LeAudioClientInterface::Sink::CancelStreamingRequest() {}
UpdateAudioConfigToHal(const::bluetooth::le_audio::offload_config &)183 void LeAudioClientInterface::Sink::UpdateAudioConfigToHal(
184         const ::bluetooth::le_audio::offload_config& /*config*/) {}
UpdateBroadcastAudioConfigToHal(const::bluetooth::le_audio::broadcast_offload_config &)185 void LeAudioClientInterface::Sink::UpdateBroadcastAudioConfigToHal(
186         const ::bluetooth::le_audio::broadcast_offload_config& /*config*/) {}
187 std::optional<::le_audio::broadcaster::BroadcastConfiguration>
GetBroadcastConfig(const std::vector<std::pair<::le_audio::types::LeAudioContextType,uint8_t>> & quality,const std::optional<std::vector<::bluetooth::le_audio::types::acs_ac_record>> & pacs) const188 LeAudioClientInterface::Sink::GetBroadcastConfig(
189         const std::vector<std::pair<::le_audio::types::LeAudioContextType, uint8_t>>& quality,
190         const std::optional<std::vector<::bluetooth::le_audio::types::acs_ac_record>>& pacs) const {
191   return sink_mock->GetBroadcastConfig(quality, pacs);
192 }
193 std::optional<::le_audio::set_configurations::AudioSetConfiguration>
GetUnicastConfig(const::bluetooth::le_audio::CodecManager::UnicastConfigurationRequirements & requirements) const194 LeAudioClientInterface::Sink::GetUnicastConfig(
195         const ::bluetooth::le_audio::CodecManager::UnicastConfigurationRequirements& requirements)
196         const {
197   return sink_mock->GetUnicastConfig(requirements);
198 }
SuspendedForReconfiguration()199 void LeAudioClientInterface::Sink::SuspendedForReconfiguration() {}
ReconfigurationComplete()200 void LeAudioClientInterface::Sink::ReconfigurationComplete() {}
201 
Cleanup()202 void LeAudioClientInterface::Source::Cleanup() {}
SetPcmParameters(const PcmParameters &)203 void LeAudioClientInterface::Source::SetPcmParameters(const PcmParameters& /*params*/) {}
SetRemoteDelay(uint16_t)204 void LeAudioClientInterface::Source::SetRemoteDelay(uint16_t /*delay_report_ms*/) {}
StartSession()205 void LeAudioClientInterface::Source::StartSession() {}
StopSession()206 void LeAudioClientInterface::Source::StopSession() {}
ConfirmStreamingRequest()207 void LeAudioClientInterface::Source::ConfirmStreamingRequest() {}
CancelStreamingRequest()208 void LeAudioClientInterface::Source::CancelStreamingRequest() {}
UpdateAudioConfigToHal(const::bluetooth::le_audio::offload_config &)209 void LeAudioClientInterface::Source::UpdateAudioConfigToHal(
210         const ::bluetooth::le_audio::offload_config& /*config*/) {}
SuspendedForReconfiguration()211 void LeAudioClientInterface::Source::SuspendedForReconfiguration() {}
ReconfigurationComplete()212 void LeAudioClientInterface::Source::ReconfigurationComplete() {}
213 
Write(const uint8_t * p_buf,uint32_t len)214 size_t LeAudioClientInterface::Source::Write(const uint8_t* p_buf, uint32_t len) {
215   return source_mock->Write(p_buf, len);
216 }
217 
Read(uint8_t * p_buf,uint32_t len)218 size_t LeAudioClientInterface::Sink::Read(uint8_t* p_buf, uint32_t len) {
219   return sink_mock->Read(p_buf, len);
220 }
221 }  // namespace le_audio
222 }  // namespace audio
223 }  // namespace bluetooth
224 
225 class MockLeAudioClientAudioSinkEventReceiver : public LeAudioSourceAudioHalClient::Callbacks {
226 public:
227   MOCK_METHOD((void), OnAudioDataReady, (const std::vector<uint8_t>& data), (override));
228   MOCK_METHOD((void), OnAudioSuspend, (), (override));
229   MOCK_METHOD((void), OnAudioResume, (), (override));
230   MOCK_METHOD((void), OnAudioMetadataUpdate,
231               (const std::vector<struct playback_track_metadata_v7> source_metadata,
232                DsaMode dsa_mode),
233               (override));
234 };
235 
236 class MockAudioHalClientEventReceiver : public LeAudioSinkAudioHalClient::Callbacks {
237 public:
238   MOCK_METHOD((void), OnAudioSuspend, (), (override));
239   MOCK_METHOD((void), OnAudioResume, (), (override));
240   MOCK_METHOD((void), OnAudioMetadataUpdate,
241               (const std::vector<struct record_track_metadata_v7> sink_metadata), (override));
242 };
243 
244 class LeAudioClientAudioTest : public ::testing::Test {
245 protected:
SetUp(void)246   void SetUp(void) override {
247     init_message_loop_thread();
248     bluetooth::audio::le_audio::interface_mock = &mock_client_interface_;
249     bluetooth::audio::le_audio::sink_mock = &mock_hal_interface_audio_sink_;
250     bluetooth::audio::le_audio::source_mock = &mock_hal_interface_audio_source_;
251 
252     // Init sink Audio HAL mock
253     is_sink_audio_hal_acquired = false;
254     sink_audio_hal_stream_cb = {.on_resume_ = nullptr, .on_suspend_ = nullptr};
255 
256     ON_CALL(mock_client_interface_, GetSink(_, _, _))
257             .WillByDefault(DoAll(SaveArg<0>(&sink_audio_hal_stream_cb),
258                                  Assign(&is_sink_audio_hal_acquired, true),
259                                  Return(bluetooth::audio::le_audio::sink_mock)));
260     ON_CALL(mock_hal_interface_audio_sink_, Cleanup())
261             .WillByDefault(Assign(&is_sink_audio_hal_acquired, false));
262 
263     // Init source Audio HAL mock
264     is_source_audio_hal_acquired = false;
265     source_audio_hal_stream_cb = {.on_resume_ = nullptr, .on_suspend_ = nullptr};
266 
267     ON_CALL(mock_client_interface_, GetSource(_, _))
268             .WillByDefault(DoAll(SaveArg<0>(&source_audio_hal_stream_cb),
269                                  Assign(&is_source_audio_hal_acquired, true),
270                                  Return(bluetooth::audio::le_audio::source_mock)));
271     ON_CALL(mock_hal_interface_audio_source_, Cleanup())
272             .WillByDefault(Assign(&is_source_audio_hal_acquired, false));
273   }
274 
AcquireLeAudioSinkHalClient(void)275   bool AcquireLeAudioSinkHalClient(void) {
276     audio_sink_instance_ = LeAudioSinkAudioHalClient::AcquireUnicast();
277     return is_source_audio_hal_acquired;
278   }
279 
ReleaseLeAudioSinkHalClient(void)280   bool ReleaseLeAudioSinkHalClient(void) {
281     audio_sink_instance_.reset();
282     return !is_source_audio_hal_acquired;
283   }
284 
AcquireLeAudioSourceHalClient(void)285   bool AcquireLeAudioSourceHalClient(void) {
286     audio_source_instance_ = LeAudioSourceAudioHalClient::AcquireUnicast();
287     return is_sink_audio_hal_acquired;
288   }
289 
ReleaseLeAudioSourceHalClient(void)290   bool ReleaseLeAudioSourceHalClient(void) {
291     audio_source_instance_.reset();
292     return !is_sink_audio_hal_acquired;
293   }
294 
TearDown(void)295   void TearDown(void) override {
296     com::android::bluetooth::flags::provider_->reset_flags();
297 
298     /* We have to call Cleanup to tidy up some static variables.
299      * If on the HAL end Source is running it means we are running the Sink
300      * on our end, and vice versa.
301      */
302     if (is_source_audio_hal_acquired == true) {
303       ReleaseLeAudioSinkHalClient();
304     }
305     if (is_sink_audio_hal_acquired == true) {
306       ReleaseLeAudioSourceHalClient();
307     }
308 
309     cleanup_message_loop_thread();
310 
311     bluetooth::audio::le_audio::sink_mock = nullptr;
312     bluetooth::audio::le_audio::source_mock = nullptr;
313   }
314 
315   MockLeAudioClientInterface mock_client_interface_;
316   MockLeAudioClientInterfaceSink mock_hal_interface_audio_sink_;
317   MockLeAudioClientInterfaceSource mock_hal_interface_audio_source_;
318 
319   MockLeAudioClientAudioSinkEventReceiver mock_hal_sink_event_receiver_;
320   MockAudioHalClientEventReceiver mock_hal_source_event_receiver_;
321 
322   bool is_source_audio_hal_acquired = false;
323   bool is_sink_audio_hal_acquired = false;
324   std::unique_ptr<LeAudioSinkAudioHalClient> audio_sink_instance_;
325   std::unique_ptr<LeAudioSourceAudioHalClient> audio_source_instance_;
326 
327   bluetooth::audio::le_audio::StreamCallbacks source_audio_hal_stream_cb;
328   bluetooth::audio::le_audio::StreamCallbacks sink_audio_hal_stream_cb;
329 
330   const LeAudioCodecConfiguration default_codec_conf{
331           .num_channels = LeAudioCodecConfiguration::kChannelNumberMono,
332           .sample_rate = LeAudioCodecConfiguration::kSampleRate44100,
333           .bits_per_sample = LeAudioCodecConfiguration::kBitsPerSample24,
334           .data_interval_us = LeAudioCodecConfiguration::kInterval10000Us,
335   };
336 };
337 
TEST_F(LeAudioClientAudioTest,testLeAudioClientAudioSinkInitializeCleanup)338 TEST_F(LeAudioClientAudioTest, testLeAudioClientAudioSinkInitializeCleanup) {
339   EXPECT_CALL(mock_client_interface_, GetSource(_, _));
340   ASSERT_TRUE(AcquireLeAudioSinkHalClient());
341 
342   EXPECT_CALL(mock_hal_interface_audio_source_, Cleanup());
343   ASSERT_TRUE(ReleaseLeAudioSinkHalClient());
344 }
345 
TEST_F(LeAudioClientAudioTest,testAudioHalClientInitializeCleanup)346 TEST_F(LeAudioClientAudioTest, testAudioHalClientInitializeCleanup) {
347   EXPECT_CALL(mock_client_interface_, GetSink(_, _, _));
348   ASSERT_TRUE(AcquireLeAudioSourceHalClient());
349 
350   EXPECT_CALL(mock_hal_interface_audio_sink_, Cleanup());
351   ASSERT_TRUE(ReleaseLeAudioSourceHalClient());
352 }
353 
TEST_F(LeAudioClientAudioTest,testLeAudioClientAudioSinkStartStop)354 TEST_F(LeAudioClientAudioTest, testLeAudioClientAudioSinkStartStop) {
355   LeAudioClientInterface::PcmParameters params;
356   EXPECT_CALL(mock_hal_interface_audio_source_, SetPcmParameters(_))
357           .Times(1)
358           .WillOnce(SaveArg<0>(&params));
359   EXPECT_CALL(mock_hal_interface_audio_source_, StartSession()).Times(1);
360 
361   ASSERT_TRUE(AcquireLeAudioSinkHalClient());
362   ASSERT_TRUE(audio_sink_instance_->Start(default_codec_conf, &mock_hal_source_event_receiver_));
363 
364   ASSERT_EQ(params.channels_count, bluetooth::audio::le_audio::kChannelNumberMono);
365   ASSERT_EQ(params.sample_rate, bluetooth::audio::le_audio::kSampleRate44100);
366   ASSERT_EQ(params.bits_per_sample, bluetooth::audio::le_audio::kBitsPerSample24);
367   ASSERT_EQ(params.data_interval_us, 10000u);
368 
369   EXPECT_CALL(mock_hal_interface_audio_source_, StopSession()).Times(1);
370 
371   audio_sink_instance_->Stop();
372 }
373 
TEST_F(LeAudioClientAudioTest,testAudioHalClientStartStop)374 TEST_F(LeAudioClientAudioTest, testAudioHalClientStartStop) {
375   LeAudioClientInterface::PcmParameters params;
376   EXPECT_CALL(mock_hal_interface_audio_sink_, SetPcmParameters(_))
377           .Times(1)
378           .WillOnce(SaveArg<0>(&params));
379   EXPECT_CALL(mock_hal_interface_audio_sink_, StartSession()).Times(1);
380 
381   ASSERT_TRUE(AcquireLeAudioSourceHalClient());
382   ASSERT_TRUE(audio_source_instance_->Start(default_codec_conf, &mock_hal_sink_event_receiver_));
383 
384   ASSERT_EQ(params.channels_count, bluetooth::audio::le_audio::kChannelNumberMono);
385   ASSERT_EQ(params.sample_rate, bluetooth::audio::le_audio::kSampleRate44100);
386   ASSERT_EQ(params.bits_per_sample, bluetooth::audio::le_audio::kBitsPerSample24);
387   ASSERT_EQ(params.data_interval_us, 10000u);
388 
389   EXPECT_CALL(mock_hal_interface_audio_sink_, StopSession()).Times(1);
390 
391   audio_source_instance_->Stop();
392 }
393 
TEST_F(LeAudioClientAudioTest,testLeAudioClientAudioSinkSendData)394 TEST_F(LeAudioClientAudioTest, testLeAudioClientAudioSinkSendData) {
395   ASSERT_TRUE(AcquireLeAudioSinkHalClient());
396   ASSERT_TRUE(audio_sink_instance_->Start(default_codec_conf, &mock_hal_source_event_receiver_));
397 
398   const uint8_t* exp_p = nullptr;
399   uint32_t exp_len = 0;
400   uint8_t input_buf[] = {
401           0x02,
402           0x03,
403           0x05,
404           0x19,
405   };
406   ON_CALL(mock_hal_interface_audio_source_, Write(_, _))
407           .WillByDefault(DoAll(SaveArg<0>(&exp_p), SaveArg<1>(&exp_len), ReturnPointee(&exp_len)));
408 
409   ASSERT_EQ(audio_sink_instance_->SendData(input_buf, sizeof(input_buf)), sizeof(input_buf));
410   ASSERT_EQ(exp_len, sizeof(input_buf));
411   ASSERT_EQ(exp_p, input_buf);
412 
413   audio_sink_instance_->Stop();
414 }
415 
TEST_F(LeAudioClientAudioTest,testLeAudioClientAudioSinkSuspend)416 TEST_F(LeAudioClientAudioTest, testLeAudioClientAudioSinkSuspend) {
417   ASSERT_TRUE(AcquireLeAudioSinkHalClient());
418   ASSERT_TRUE(audio_sink_instance_->Start(default_codec_conf, &mock_hal_source_event_receiver_));
419 
420   ASSERT_NE(source_audio_hal_stream_cb.on_suspend_, nullptr);
421 
422   /* Expect LeAudio registered event listener to get called when HAL calls the
423    * audio_hal_client's internal suspend callback.
424    */
425   EXPECT_CALL(mock_hal_source_event_receiver_, OnAudioSuspend()).Times(1);
426   ASSERT_TRUE(source_audio_hal_stream_cb.on_suspend_());
427 }
428 
TEST_F(LeAudioClientAudioTest,testAudioHalClientSuspend)429 TEST_F(LeAudioClientAudioTest, testAudioHalClientSuspend) {
430   ASSERT_TRUE(AcquireLeAudioSourceHalClient());
431   ASSERT_TRUE(audio_source_instance_->Start(default_codec_conf, &mock_hal_sink_event_receiver_));
432 
433   ASSERT_NE(sink_audio_hal_stream_cb.on_suspend_, nullptr);
434 
435   /* Expect LeAudio registered event listener to get called when HAL calls the
436    * audio_hal_client's internal suspend callback.
437    */
438   EXPECT_CALL(mock_hal_sink_event_receiver_, OnAudioSuspend()).Times(1);
439   ASSERT_TRUE(sink_audio_hal_stream_cb.on_suspend_());
440 }
441 
TEST_F(LeAudioClientAudioTest,testLeAudioClientAudioSinkResume)442 TEST_F(LeAudioClientAudioTest, testLeAudioClientAudioSinkResume) {
443   ASSERT_TRUE(AcquireLeAudioSinkHalClient());
444   ASSERT_TRUE(audio_sink_instance_->Start(default_codec_conf, &mock_hal_source_event_receiver_));
445 
446   ASSERT_NE(source_audio_hal_stream_cb.on_resume_, nullptr);
447 
448   /* Expect LeAudio registered event listener to get called when HAL calls the
449    * audio_hal_client's internal resume callback.
450    */
451   EXPECT_CALL(mock_hal_source_event_receiver_, OnAudioResume()).Times(1);
452   bool start_media_task = false;
453   ASSERT_TRUE(source_audio_hal_stream_cb.on_resume_(start_media_task));
454 }
455 
TEST_F(LeAudioClientAudioTest,testAudioHalClientResumeStartSourceTask_workerEnabled)456 TEST_F(LeAudioClientAudioTest, testAudioHalClientResumeStartSourceTask_workerEnabled) {
457   com::android::bluetooth::flags::provider_->run_ble_audio_ticks_in_worker_thread(true);
458 
459   const LeAudioCodecConfiguration codec_conf{
460           .num_channels = LeAudioCodecConfiguration::kChannelNumberStereo,
461           .sample_rate = LeAudioCodecConfiguration::kSampleRate16000,
462           .bits_per_sample = LeAudioCodecConfiguration::kBitsPerSample24,
463           .data_interval_us = LeAudioCodecConfiguration::kInterval10000Us,
464   };
465   ASSERT_TRUE(AcquireLeAudioSourceHalClient());
466   ASSERT_TRUE(audio_source_instance_->Start(codec_conf, &mock_hal_sink_event_receiver_));
467 
468   std::promise<void> promise;
469   auto future = promise.get_future();
470 
471   uint32_t calculated_bytes_per_tick = 0;
472   EXPECT_CALL(mock_hal_interface_audio_sink_, Read(_, _))
473           .Times(AtLeast(1))
474           .WillOnce(Invoke([&](uint8_t* p_buf, uint32_t len) -> uint32_t {
475             calculated_bytes_per_tick = len;
476 
477             // fake some data from audio framework
478             for (uint32_t i = 0u; i < len; ++i) {
479               p_buf[i] = i;
480             }
481 
482             // Return exactly as much data as requested
483             promise.set_value();
484             return len;
485           }))
486           .WillRepeatedly(Invoke([](uint8_t* p_buf, uint32_t len) -> uint32_t {
487             // fake some data from audio framework
488             for (uint32_t i = 0u; i < len; ++i) {
489               p_buf[i] = i;
490             }
491             return len;
492           }));
493 
494   std::promise<void> data_promise;
495   auto data_future = data_promise.get_future();
496 
497   /* Expect this callback to be called to Client by the HAL glue layer */
498   std::vector<uint8_t> media_data_to_send;
499   EXPECT_CALL(mock_hal_sink_event_receiver_, OnAudioDataReady(_))
500           .Times(AtLeast(1))
501           .WillOnce(Invoke([&](const std::vector<uint8_t>& data) -> void {
502             media_data_to_send = std::move(data);
503             data_promise.set_value();
504           }))
505           .WillRepeatedly(DoDefault());
506 
507   /* Expect LeAudio registered event listener to get called when HAL calls the
508    * audio_hal_client's internal resume callback.
509    */
510   ASSERT_NE(sink_audio_hal_stream_cb.on_resume_, nullptr);
511   EXPECT_CALL(mock_hal_sink_event_receiver_, OnAudioResume()).Times(1);
512   bool start_media_task = true;
513   ASSERT_TRUE(sink_audio_hal_stream_cb.on_resume_(start_media_task));
514   audio_source_instance_->ConfirmStreamingRequest();
515 
516   ASSERT_EQ(future.wait_for(std::chrono::seconds(1)), std::future_status::ready);
517 
518   ASSERT_EQ(data_future.wait_for(std::chrono::seconds(1)), std::future_status::ready);
519 
520   // Check against expected payload size
521   // 24 bit audio stream is sent as unpacked, each sample takes 4 bytes.
522   const uint32_t channel_bytes_per_sample = 4;
523   const uint32_t channel_bytes_per_10ms_at_16000Hz =
524           ((10ms).count() * channel_bytes_per_sample * 16000 /*Hz*/) / (1000ms).count();
525 
526   // Expect 2 channel (stereo) data
527   ASSERT_EQ(calculated_bytes_per_tick, 2 * channel_bytes_per_10ms_at_16000Hz);
528 
529   // Verify if we got just right amount of data in the callback call
530   ASSERT_EQ(media_data_to_send.size(), calculated_bytes_per_tick);
531 }
532 
TEST_F(LeAudioClientAudioTest,testAudioHalClientResumeStartSourceTask)533 TEST_F(LeAudioClientAudioTest, testAudioHalClientResumeStartSourceTask) {
534   const LeAudioCodecConfiguration codec_conf{
535           .num_channels = LeAudioCodecConfiguration::kChannelNumberStereo,
536           .sample_rate = LeAudioCodecConfiguration::kSampleRate16000,
537           .bits_per_sample = LeAudioCodecConfiguration::kBitsPerSample24,
538           .data_interval_us = LeAudioCodecConfiguration::kInterval10000Us,
539   };
540   ASSERT_TRUE(AcquireLeAudioSourceHalClient());
541   ASSERT_TRUE(audio_source_instance_->Start(codec_conf, &mock_hal_sink_event_receiver_));
542 
543   std::promise<void> promise;
544   auto future = promise.get_future();
545 
546   uint32_t calculated_bytes_per_tick = 0;
547   EXPECT_CALL(mock_hal_interface_audio_sink_, Read(_, _))
548           .Times(AtLeast(1))
549           .WillOnce(Invoke([&](uint8_t* p_buf, uint32_t len) -> uint32_t {
550             calculated_bytes_per_tick = len;
551 
552             // fake some data from audio framework
553             for (uint32_t i = 0u; i < len; ++i) {
554               p_buf[i] = i;
555             }
556 
557             // Return exactly as much data as requested
558             promise.set_value();
559             return len;
560           }))
561           .WillRepeatedly(Invoke([](uint8_t* p_buf, uint32_t len) -> uint32_t {
562             // fake some data from audio framework
563             for (uint32_t i = 0u; i < len; ++i) {
564               p_buf[i] = i;
565             }
566             return len;
567           }));
568 
569   std::promise<void> data_promise;
570   auto data_future = data_promise.get_future();
571 
572   /* Expect this callback to be called to Client by the HAL glue layer */
573   std::vector<uint8_t> media_data_to_send;
574   EXPECT_CALL(mock_hal_sink_event_receiver_, OnAudioDataReady(_))
575           .Times(AtLeast(1))
576           .WillOnce(Invoke([&](const std::vector<uint8_t>& data) -> void {
577             media_data_to_send = std::move(data);
578             data_promise.set_value();
579           }))
580           .WillRepeatedly(DoDefault());
581 
582   /* Expect LeAudio registered event listener to get called when HAL calls the
583    * audio_hal_client's internal resume callback.
584    */
585   ASSERT_NE(sink_audio_hal_stream_cb.on_resume_, nullptr);
586   EXPECT_CALL(mock_hal_sink_event_receiver_, OnAudioResume()).Times(1);
587   bool start_media_task = true;
588   ASSERT_TRUE(sink_audio_hal_stream_cb.on_resume_(start_media_task));
589   audio_source_instance_->ConfirmStreamingRequest();
590 
591   ASSERT_EQ(future.wait_for(std::chrono::seconds(1)), std::future_status::ready);
592 
593   ASSERT_EQ(data_future.wait_for(std::chrono::seconds(1)), std::future_status::ready);
594 
595   // Check agains expected payload size
596   // 24 bit audio stream is sent as unpacked, each sample takes 4 bytes.
597   const uint32_t channel_bytes_per_sample = 4;
598   const uint32_t channel_bytes_per_10ms_at_16000Hz =
599           ((10ms).count() * channel_bytes_per_sample * 16000 /*Hz*/) / (1000ms).count();
600 
601   // Expect 2 channel (stereo) data
602   ASSERT_EQ(calculated_bytes_per_tick, 2 * channel_bytes_per_10ms_at_16000Hz);
603 
604   // Verify if we got just right amount of data in the callback call
605   ASSERT_EQ(media_data_to_send.size(), calculated_bytes_per_tick);
606 }
607 
TEST_F(LeAudioClientAudioTest,testAudioHalClientResume)608 TEST_F(LeAudioClientAudioTest, testAudioHalClientResume) {
609   ASSERT_TRUE(AcquireLeAudioSourceHalClient());
610   ASSERT_TRUE(audio_source_instance_->Start(default_codec_conf, &mock_hal_sink_event_receiver_));
611 
612   ASSERT_NE(sink_audio_hal_stream_cb.on_resume_, nullptr);
613 
614   /* Expect LeAudio registered event listener to get called when HAL calls the
615    * audio_hal_client's internal resume callback.
616    */
617   EXPECT_CALL(mock_hal_sink_event_receiver_, OnAudioResume()).Times(1);
618   bool start_media_task = false;
619   ASSERT_TRUE(sink_audio_hal_stream_cb.on_resume_(start_media_task));
620 }
621