Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6a5e0e1e authored by Łukasz Rymanowski (xWF)'s avatar Łukasz Rymanowski (xWF) Committed by Gerrit Code Review
Browse files

Merge "audio_source_hal_client: Do not use Unretained(this)" into main

parents cea871fd 87ff7692
Loading
Loading
Loading
Loading
+79 −0
Original line number Diff line number Diff line
@@ -292,6 +292,8 @@ protected:
  }

  void TearDown(void) override {
    com::android::bluetooth::flags::provider_->reset_flags();

    /* We have to call Cleanup to tidy up some static variables.
     * If on the HAL end Source is running it means we are running the Sink
     * on our end, and vice versa.
@@ -450,6 +452,83 @@ TEST_F(LeAudioClientAudioTest, testLeAudioClientAudioSinkResume) {
  ASSERT_TRUE(source_audio_hal_stream_cb.on_resume_(start_media_task));
}

TEST_F(LeAudioClientAudioTest, testAudioHalClientResumeStartSourceTask_workerEnabled) {
  com::android::bluetooth::flags::provider_->run_ble_audio_ticks_in_worker_thread(true);

  const LeAudioCodecConfiguration codec_conf{
          .num_channels = LeAudioCodecConfiguration::kChannelNumberStereo,
          .sample_rate = LeAudioCodecConfiguration::kSampleRate16000,
          .bits_per_sample = LeAudioCodecConfiguration::kBitsPerSample24,
          .data_interval_us = LeAudioCodecConfiguration::kInterval10000Us,
  };
  ASSERT_TRUE(AcquireLeAudioSourceHalClient());
  ASSERT_TRUE(audio_source_instance_->Start(codec_conf, &mock_hal_sink_event_receiver_));

  std::promise<void> promise;
  auto future = promise.get_future();

  uint32_t calculated_bytes_per_tick = 0;
  EXPECT_CALL(mock_hal_interface_audio_sink_, Read(_, _))
          .Times(AtLeast(1))
          .WillOnce(Invoke([&](uint8_t* p_buf, uint32_t len) -> uint32_t {
            calculated_bytes_per_tick = len;

            // fake some data from audio framework
            for (uint32_t i = 0u; i < len; ++i) {
              p_buf[i] = i;
            }

            // Return exactly as much data as requested
            promise.set_value();
            return len;
          }))
          .WillRepeatedly(Invoke([](uint8_t* p_buf, uint32_t len) -> uint32_t {
            // fake some data from audio framework
            for (uint32_t i = 0u; i < len; ++i) {
              p_buf[i] = i;
            }
            return len;
          }));

  std::promise<void> data_promise;
  auto data_future = data_promise.get_future();

  /* Expect this callback to be called to Client by the HAL glue layer */
  std::vector<uint8_t> media_data_to_send;
  EXPECT_CALL(mock_hal_sink_event_receiver_, OnAudioDataReady(_))
          .Times(AtLeast(1))
          .WillOnce(Invoke([&](const std::vector<uint8_t>& data) -> void {
            media_data_to_send = std::move(data);
            data_promise.set_value();
          }))
          .WillRepeatedly(DoDefault());

  /* Expect LeAudio registered event listener to get called when HAL calls the
   * audio_hal_client's internal resume callback.
   */
  ASSERT_NE(sink_audio_hal_stream_cb.on_resume_, nullptr);
  EXPECT_CALL(mock_hal_sink_event_receiver_, OnAudioResume()).Times(1);
  bool start_media_task = true;
  ASSERT_TRUE(sink_audio_hal_stream_cb.on_resume_(start_media_task));
  audio_source_instance_->ConfirmStreamingRequest();

  ASSERT_EQ(future.wait_for(std::chrono::seconds(1)), std::future_status::ready);

  ASSERT_EQ(data_future.wait_for(std::chrono::seconds(1)), std::future_status::ready);

  // Check against expected payload size
  // 24 bit audio stream is sent as unpacked, each sample takes 4 bytes.
  const uint32_t channel_bytes_per_sample = 4;
  const uint32_t channel_bytes_per_10ms_at_16000Hz =
          ((10ms).count() * channel_bytes_per_sample * 16000 /*Hz*/) / (1000ms).count();

  // Expect 2 channel (stereo) data
  ASSERT_EQ(calculated_bytes_per_tick, 2 * channel_bytes_per_10ms_at_16000Hz);

  // Verify if we got just right amount of data in the callback call
  ASSERT_EQ(media_data_to_send.size(), calculated_bytes_per_tick);
}

TEST_F(LeAudioClientAudioTest, testAudioHalClientResumeStartSourceTask) {
  const LeAudioCodecConfiguration codec_conf{
          .num_channels = LeAudioCodecConfiguration::kChannelNumberStereo,
+6 −4
Original line number Diff line number Diff line
@@ -109,6 +109,8 @@ public:
  LeAudioSourceAudioHalClient::Callbacks* audioSourceCallbacks_ = nullptr;
  std::mutex audioSourceCallbacksMutex_;
  std::unique_ptr<bluetooth::audio::asrc::SourceAudioHalAsrc> asrc_;

  base::WeakPtrFactory<SourceImpl> weak_factory_{this};
};

bool SourceImpl::Acquire() {
@@ -258,7 +260,7 @@ void SourceImpl::StartAudioTicks() {
  }
  audio_timer_.SchedulePeriodic(
          worker_thread_->GetWeakPtr(), FROM_HERE,
          base::BindRepeating(&SourceImpl::SendAudioData, base::Unretained(this)),
          base::BindRepeating(&SourceImpl::SendAudioData, weak_factory_.GetWeakPtr()),
          std::chrono::microseconds(source_codec_config_.data_interval_us));
}

@@ -273,7 +275,7 @@ bool SourceImpl::OnSuspendReq() {
  if (CodecManager::GetInstance()->GetCodecLocation() == types::CodecLocation::HOST) {
    if (com::android::bluetooth::flags::run_ble_audio_ticks_in_worker_thread()) {
      worker_thread_->DoInThread(
              FROM_HERE, base::BindOnce(&SourceImpl::StopAudioTicks, base::Unretained(this)));
              FROM_HERE, base::BindOnce(&SourceImpl::StopAudioTicks, weak_factory_.GetWeakPtr()));
    } else {
      StopAudioTicks();
    }
@@ -372,7 +374,7 @@ void SourceImpl::Stop() {
  if (CodecManager::GetInstance()->GetCodecLocation() == types::CodecLocation::HOST) {
    if (com::android::bluetooth::flags::run_ble_audio_ticks_in_worker_thread()) {
      worker_thread_->DoInThread(
              FROM_HERE, base::BindOnce(&SourceImpl::StopAudioTicks, base::Unretained(this)));
              FROM_HERE, base::BindOnce(&SourceImpl::StopAudioTicks, weak_factory_.GetWeakPtr()));
    } else {
      StopAudioTicks();
    }
@@ -400,7 +402,7 @@ void SourceImpl::ConfirmStreamingRequest() {

  if (com::android::bluetooth::flags::run_ble_audio_ticks_in_worker_thread()) {
    worker_thread_->DoInThread(
            FROM_HERE, base::BindOnce(&SourceImpl::StartAudioTicks, base::Unretained(this)));
            FROM_HERE, base::BindOnce(&SourceImpl::StartAudioTicks, weak_factory_.GetWeakPtr()));
  } else {
    StartAudioTicks();
  }