blob: e82cbde64f19b88d1f94c95e677dc2a3d286b527 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <fuchsia/media/cpp/fidl.h>
#include <fuchsia/virtualaudio/cpp/fidl.h>
#include <cmath>
#include <cstring>
#include "gtest/gtest.h"
#include "lib/component/cpp/environment_services_helper.h"
#include "src/lib/fxl/logging.h"
#include "src/media/audio/audio_core/test/virtual_audio_device_test.h"
namespace media::audio::test {
//
// VirtualAudioSystemGainTest declaration
//
// These tests verifies async usage of AudioDeviceEnumerator w/SystemGain.
class VirtualAudioSystemGainTest : public VirtualAudioDeviceTest {
protected:
void SetUp() override;
void TearDown() override;
bool ExpectCallback() override;
void AddDeviceForSystemGainTesting(bool is_input);
void ChangeAndVerifySystemGain();
void ChangeAndVerifySystemMute();
void TestDeviceGainAfterChangeSystemGainMute(bool use_get_devices,
bool is_input, bool set_gain);
void TestOnDeviceGainChangedAfterChangeSystemGainMute(bool is_input,
bool set_gain);
static constexpr float kInitialSystemGainDb = -12.0f;
static constexpr float kChangedSystemGainDb = -2.0f;
fuchsia::media::AudioCorePtr audio_core_;
float received_system_gain_db_ = NAN;
bool received_system_mute_;
};
//
// VirtualAudioSystemGainTest implementation
//
void VirtualAudioSystemGainTest::SetUp() {
VirtualAudioDeviceTest::SetUp();
environment_services_->ConnectToService(audio_core_.NewRequest());
audio_core_.set_error_handler(
[this](zx_status_t error) { error_occurred_ = true; });
audio_core_.events().SystemGainMuteChanged = [this](float gain_db,
bool muted) {
received_callback_ = true;
received_system_gain_db_ = gain_db;
received_system_mute_ = muted;
};
ASSERT_TRUE(ExpectCallback());
if (received_system_gain_db_ != kInitialSystemGainDb) {
audio_core_->SetSystemGain(kInitialSystemGainDb);
ASSERT_TRUE(ExpectCallback());
}
if (received_system_mute_) {
audio_core_->SetSystemMute(false);
ASSERT_TRUE(ExpectCallback());
}
// received_system_gain_db_/received_system_mute_ now contain initial state.
}
void VirtualAudioSystemGainTest::TearDown() {
audio_core_->SetSystemGain(kInitialSystemGainDb);
audio_core_->SetSystemMute(false);
audio_core_.set_error_handler(nullptr);
VirtualAudioDeviceTest::TearDown();
}
bool VirtualAudioSystemGainTest::ExpectCallback() {
received_system_gain_db_ = NAN;
return VirtualAudioDeviceTest::ExpectCallback();
}
void VirtualAudioSystemGainTest::AddDeviceForSystemGainTesting(bool is_input) {
float system_gain_db = received_system_gain_db_;
bool system_mute = received_system_mute_;
SetOnDeviceAddedEvent();
std::array<uint8_t, 16> unique_id{0};
VirtualAudioDeviceTest::PopulateUniqueIdArr(is_input, unique_id.data());
if (is_input) {
input_->SetGainProperties(-160.0f, 24.0f, 0.25f, kInitialSystemGainDb, true,
false, false, false);
input_->SetUniqueId(unique_id);
input_->Add();
} else {
output_->SetGainProperties(-160.0f, 24.0f, 0.25f, kInitialSystemGainDb,
true, false, false, false);
output_->SetUniqueId(unique_id);
output_->Add();
}
ASSERT_TRUE(ExpectCallback());
uint64_t added_token = received_device_.token_id;
ASSERT_NE(added_token, ZX_KOID_INVALID);
// If the device is different than expected, set it up as we expect.
if ((received_device_.gain_info.gain_db != kInitialSystemGainDb) ||
((received_device_.gain_info.flags &
fuchsia::media::AudioGainInfoFlag_Mute) != 0) ||
((received_device_.gain_info.flags &
fuchsia::media::AudioGainInfoFlag_AgcEnabled) != 0)) {
fuchsia::media::AudioGainInfo gain_info = {.gain_db = kInitialSystemGainDb,
.flags = 0};
uint32_t set_flags = fuchsia::media::SetAudioGainFlag_GainValid |
fuchsia::media::SetAudioGainFlag_MuteValid |
fuchsia::media::SetAudioGainFlag_AgcValid;
SetOnDeviceGainChangedEvent();
audio_dev_enum_->SetDeviceGain(added_token, gain_info, set_flags);
ASSERT_TRUE(ExpectCallback());
}
if (system_gain_db != kInitialSystemGainDb) {
audio_core_->SetSystemGain(kInitialSystemGainDb);
ASSERT_TRUE(ExpectCallback());
}
if (system_mute) {
audio_core_->SetSystemMute(false);
ASSERT_TRUE(ExpectCallback());
}
received_device_.token_id = added_token;
}
void VirtualAudioSystemGainTest::ChangeAndVerifySystemGain() {
float expect_gain_db = kChangedSystemGainDb;
bool expect_mute = false;
audio_core_->SetSystemGain(expect_gain_db);
ASSERT_TRUE(ExpectCallback());
ASSERT_EQ(received_system_gain_db_, expect_gain_db);
ASSERT_EQ(received_system_mute_, expect_mute);
}
void VirtualAudioSystemGainTest::ChangeAndVerifySystemMute() {
float expect_gain_db = kInitialSystemGainDb;
bool expect_mute = true;
audio_core_->SetSystemMute(expect_mute);
ASSERT_TRUE(ExpectCallback());
ASSERT_EQ(received_system_gain_db_, expect_gain_db);
ASSERT_EQ(received_system_mute_, expect_mute);
}
// Add device, get its token and gain baseline
// Change System Gain or Mute, verify System change
// Get device gain via GetDevices, verify the change(s?)
void VirtualAudioSystemGainTest::TestDeviceGainAfterChangeSystemGainMute(
bool use_get_devices, bool is_input, bool set_gain) {
if (HasPreExistingDevices()) {
FXL_DLOG(INFO) << "Test case requires an environment with no audio devices";
return;
}
AddDeviceForSystemGainTesting(is_input);
ASSERT_NE(received_device_.token_id, ZX_KOID_INVALID);
uint64_t added_token = received_device_.token_id;
if (set_gain) {
ChangeAndVerifySystemGain();
} else {
ChangeAndVerifySystemMute();
}
if (use_get_devices) {
RetrieveGainInfoUsingGetDevices(added_token);
} else {
RetrieveGainInfoUsingGetDeviceGain(added_token);
}
float expect_gain_db =
((set_gain && !is_input) ? kChangedSystemGainDb : kInitialSystemGainDb);
uint32_t expect_gain_flags =
((set_gain || is_input) ? 0 : fuchsia::media::AudioGainInfoFlag_Mute);
EXPECT_EQ(received_gain_info_.gain_db, expect_gain_db);
EXPECT_EQ(received_gain_info_.flags, expect_gain_flags);
}
void VirtualAudioSystemGainTest::
TestOnDeviceGainChangedAfterChangeSystemGainMute(bool is_input,
bool set_gain) {
if (HasPreExistingDevices()) {
FXL_DLOG(INFO) << "Test case requires an environment with no audio devices";
return;
}
float expect_gain_db = kInitialSystemGainDb;
bool expect_mute = false;
// First add a virtual device, and reset device & system gains.
AddDeviceForSystemGainTesting(is_input);
ASSERT_NE(received_device_.token_id, ZX_KOID_INVALID);
uint64_t added_token = received_device_.token_id;
// With SystemGain and DeviceGain events set, change System Gain or Mute
SetOnDeviceGainChangedEvent();
if (set_gain) {
expect_gain_db = kChangedSystemGainDb;
audio_core_->SetSystemGain(expect_gain_db);
} else {
expect_mute = true;
audio_core_->SetSystemMute(expect_mute);
}
// Wait for both callback events to arrive (indeterminate order).
fuchsia::media::AudioGainInfo gain_info = kInvalidGainInfo;
float system_gain_db = NAN;
bool system_mute = false;
// SystemGain only takes effect upon Output devices
bool need_device_event = !is_input;
bool need_system_event = true;
while (need_device_event || need_system_event) {
if (!ExpectCallback()) {
break;
}
if (received_gain_token_ != kInvalidDeviceToken) {
EXPECT_EQ(received_gain_token_, added_token);
gain_info = received_gain_info_;
need_device_event = false;
}
if (!isnan(received_system_gain_db_)) {
system_gain_db = received_system_gain_db_;
system_mute = received_system_mute_;
need_system_event = false;
}
}
EXPECT_EQ(expect_gain_db, system_gain_db);
EXPECT_EQ(expect_mute, system_mute);
// Received Output device gain/mute should equal the system gain/mute sent.
if (!is_input) {
EXPECT_EQ(expect_gain_db, gain_info.gain_db);
EXPECT_EQ(expect_mute, ((gain_info.flags &
fuchsia::media::AudioGainInfoFlag_Mute) != 0));
} else {
EXPECT_TRUE(isnan(gain_info.gain_db));
}
}
// NO-change Gain -or- NO-change Mute
//
// VirtualAudioSystemGainTest test cases
//
TEST_F(VirtualAudioSystemGainTest, GetDevicesMatchesAddInputSetSystemGain) {
TestDeviceGainAfterChangeSystemGainMute(true, true, true);
}
TEST_F(VirtualAudioSystemGainTest, GetDevicesMatchesAddInputSetSystemMute) {
TestDeviceGainAfterChangeSystemGainMute(true, true, false);
}
TEST_F(VirtualAudioSystemGainTest, GetDeviceGainMatchesAddInputSetSystemGain) {
TestDeviceGainAfterChangeSystemGainMute(false, true, true);
}
TEST_F(VirtualAudioSystemGainTest, GetDeviceGainMatchesAddInputSetSystemMute) {
TestDeviceGainAfterChangeSystemGainMute(false, true, false);
}
TEST_F(VirtualAudioSystemGainTest,
OnDeviceGainChangedMatchesAddInputSetSystemGain) {
TestOnDeviceGainChangedAfterChangeSystemGainMute(true, true);
}
TEST_F(VirtualAudioSystemGainTest,
OnDeviceGainChangedMatchesAddOutputSetSystemGain) {
TestOnDeviceGainChangedAfterChangeSystemGainMute(false, true);
}
TEST_F(VirtualAudioSystemGainTest,
OnDeviceGainChangedMatchesAddInputSetSystemMute) {
TestOnDeviceGainChangedAfterChangeSystemGainMute(true, false);
}
TEST_F(VirtualAudioSystemGainTest,
OnDeviceGainChangedMatchesAddOutputSetSystemMute) {
TestOnDeviceGainChangedAfterChangeSystemGainMute(false, false);
}
} // namespace media::audio::test