blob: 1e3020648f2b5f8a4aadca787fc5c9f78952b0c2 [file] [log] [blame]
// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef MEDIA_AUDIO_AUDIO_SYSTEM_TEST_UTIL_H_
#define MEDIA_AUDIO_AUDIO_SYSTEM_TEST_UTIL_H_
#include "base/functional/bind.h"
#include "base/location.h"
#include "base/run_loop.h"
#include "base/threading/thread_checker.h"
#include "media/audio/audio_device_description.h"
#include "media/audio/audio_system.h"
#include "media/audio/mock_audio_manager.h"
#include "media/base/audio_parameters.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
namespace media {
// For tests only. Creates AudioSystem callbacks to be passed to AudioSystem
// methods. When AudioSystem calls such a callback, it verifies treading
// expectations and checks recieved parameters against expected values passed
// during its creation. After that it calls |on_cb_received| closure.
// Note AudioSystemCallbackExpectations object must outlive all the callbacks
// it produced, since they contain raw pointers to it.
class AudioSystemCallbackExpectations {
public:
AudioSystemCallbackExpectations() = default;
AudioSystemCallbackExpectations(const AudioSystemCallbackExpectations&) =
delete;
AudioSystemCallbackExpectations& operator=(
const AudioSystemCallbackExpectations&) = delete;
AudioSystem::OnAudioParamsCallback GetAudioParamsCallback(
const base::Location& location,
base::OnceClosure on_cb_received,
const absl::optional<AudioParameters>& expected_params);
AudioSystem::OnBoolCallback GetBoolCallback(const base::Location& location,
base::OnceClosure on_cb_received,
bool expected);
AudioSystem::OnDeviceDescriptionsCallback GetDeviceDescriptionsCallback(
const base::Location& location,
base::OnceClosure on_cb_received,
const AudioDeviceDescriptions& expected_descriptions);
AudioSystem::OnInputDeviceInfoCallback GetInputDeviceInfoCallback(
const base::Location& location,
base::OnceClosure on_cb_received,
const absl::optional<AudioParameters>& expected_input,
const absl::optional<std::string>& expected_associated_device_id);
AudioSystem::OnDeviceIdCallback GetDeviceIdCallback(
const base::Location& location,
base::OnceClosure on_cb_received,
const absl::optional<std::string>& expected_id);
private:
// Methods to verify correctness of received data.
void OnAudioParams(const std::string& from_here,
base::OnceClosure on_cb_received,
const absl::optional<AudioParameters>& expected,
const absl::optional<AudioParameters>& received);
void OnBool(const std::string& from_here,
base::OnceClosure on_cb_received,
bool expected,
bool result);
void OnDeviceDescriptions(
const std::string& from_here,
base::OnceClosure on_cb_received,
const AudioDeviceDescriptions& expected_descriptions,
AudioDeviceDescriptions descriptions);
void OnInputDeviceInfo(
const std::string& from_here,
base::OnceClosure on_cb_received,
const absl::optional<AudioParameters>& expected_input,
const absl::optional<std::string>& expected_associated_device_id,
const absl::optional<AudioParameters>& input,
const absl::optional<std::string>& associated_device_id);
void OnDeviceId(const std::string& from_here,
base::OnceClosure on_cb_received,
const absl::optional<std::string>& expected_id,
const absl::optional<std::string>& result_id);
THREAD_CHECKER(thread_checker_);
};
// Template test case to test AudioSystem implementations.
template <class T>
class AudioSystemTestTemplate : public T {
public:
AudioSystemTestTemplate() {}
AudioSystemTestTemplate(const AudioSystemTestTemplate&) = delete;
AudioSystemTestTemplate& operator=(const AudioSystemTestTemplate&) = delete;
~AudioSystemTestTemplate() override {}
void SetUp() override {
T::SetUp();
input_params_ = AudioParameters(AudioParameters::AUDIO_PCM_LINEAR,
ChannelLayoutConfig::Mono(),
AudioParameters::kTelephoneSampleRate,
AudioParameters::kTelephoneSampleRate / 10);
output_params_ = AudioParameters(
AudioParameters::AUDIO_PCM_LINEAR, ChannelLayoutConfig::Mono(),
AudioParameters::kTelephoneSampleRate,
AudioParameters::kTelephoneSampleRate / 20);
default_output_params_ = AudioParameters(
AudioParameters::AUDIO_PCM_LINEAR, ChannelLayoutConfig::Mono(),
AudioParameters::kTelephoneSampleRate,
AudioParameters::kTelephoneSampleRate / 30);
audio_manager()->SetInputStreamParameters(input_params_);
audio_manager()->SetOutputStreamParameters(output_params_);
audio_manager()->SetDefaultOutputStreamParameters(default_output_params_);
auto get_device_descriptions = [](const AudioDeviceDescriptions* source,
AudioDeviceDescriptions* destination) {
destination->insert(destination->end(), source->begin(), source->end());
};
audio_manager()->SetInputDeviceDescriptionsCallback(
base::BindRepeating(get_device_descriptions,
base::Unretained(&input_device_descriptions_)));
audio_manager()->SetOutputDeviceDescriptionsCallback(
base::BindRepeating(get_device_descriptions,
base::Unretained(&output_device_descriptions_)));
}
protected:
MockAudioManager* audio_manager() { return T::audio_manager(); }
AudioSystem* audio_system() { return T::audio_system(); }
AudioSystemCallbackExpectations expectations_;
AudioParameters input_params_;
AudioParameters output_params_;
AudioParameters default_output_params_;
AudioDeviceDescriptions input_device_descriptions_;
AudioDeviceDescriptions output_device_descriptions_;
};
TYPED_TEST_SUITE_P(AudioSystemTestTemplate);
TYPED_TEST_P(AudioSystemTestTemplate, GetInputStreamParametersNormal) {
base::RunLoop wait_loop;
this->audio_system()->GetInputStreamParameters(
AudioDeviceDescription::kDefaultDeviceId,
this->expectations_.GetAudioParamsCallback(
FROM_HERE, wait_loop.QuitClosure(), this->input_params_));
wait_loop.Run();
}
TYPED_TEST_P(AudioSystemTestTemplate, GetInputStreamParametersNoDevice) {
this->audio_manager()->SetHasInputDevices(false);
base::RunLoop wait_loop;
this->audio_system()->GetInputStreamParameters(
AudioDeviceDescription::kDefaultDeviceId,
this->expectations_.GetAudioParamsCallback(
FROM_HERE, wait_loop.QuitClosure(),
absl::optional<AudioParameters>()));
wait_loop.Run();
}
TYPED_TEST_P(AudioSystemTestTemplate, GetOutputStreamParameters) {
base::RunLoop wait_loop;
this->audio_system()->GetOutputStreamParameters(
"non-default-device-id",
this->expectations_.GetAudioParamsCallback(
FROM_HERE, wait_loop.QuitClosure(), this->output_params_));
wait_loop.Run();
}
TYPED_TEST_P(AudioSystemTestTemplate, GetDefaultOutputStreamParameters) {
base::RunLoop wait_loop;
this->audio_system()->GetOutputStreamParameters(
AudioDeviceDescription::kDefaultDeviceId,
this->expectations_.GetAudioParamsCallback(
FROM_HERE, wait_loop.QuitClosure(), this->default_output_params_));
wait_loop.Run();
}
TYPED_TEST_P(AudioSystemTestTemplate,
GetOutputStreamParametersForDefaultDeviceNoDevices) {
this->audio_manager()->SetHasOutputDevices(false);
base::RunLoop wait_loop;
this->audio_system()->GetOutputStreamParameters(
AudioDeviceDescription::kDefaultDeviceId,
this->expectations_.GetAudioParamsCallback(
FROM_HERE, wait_loop.QuitClosure(),
absl::optional<AudioParameters>()));
wait_loop.Run();
}
TYPED_TEST_P(AudioSystemTestTemplate,
GetOutputStreamParametersForNonDefaultDeviceNoDevices) {
this->audio_manager()->SetHasOutputDevices(false);
base::RunLoop wait_loop;
this->audio_system()->GetOutputStreamParameters(
"non-default-device-id", this->expectations_.GetAudioParamsCallback(
FROM_HERE, wait_loop.QuitClosure(),
absl::optional<AudioParameters>()));
wait_loop.Run();
}
TYPED_TEST_P(AudioSystemTestTemplate, HasInputDevices) {
base::RunLoop wait_loop;
this->audio_system()->HasInputDevices(this->expectations_.GetBoolCallback(
FROM_HERE, wait_loop.QuitClosure(), true));
wait_loop.Run();
}
TYPED_TEST_P(AudioSystemTestTemplate, HasNoInputDevices) {
this->audio_manager()->SetHasInputDevices(false);
base::RunLoop wait_loop;
this->audio_system()->HasInputDevices(this->expectations_.GetBoolCallback(
FROM_HERE, wait_loop.QuitClosure(), false));
wait_loop.Run();
}
TYPED_TEST_P(AudioSystemTestTemplate, HasOutputDevices) {
base::RunLoop wait_loop;
this->audio_system()->HasOutputDevices(this->expectations_.GetBoolCallback(
FROM_HERE, wait_loop.QuitClosure(), true));
wait_loop.Run();
}
TYPED_TEST_P(AudioSystemTestTemplate, HasNoOutputDevices) {
this->audio_manager()->SetHasOutputDevices(false);
base::RunLoop wait_loop;
this->audio_system()->HasOutputDevices(this->expectations_.GetBoolCallback(
FROM_HERE, wait_loop.QuitClosure(), false));
wait_loop.Run();
}
TYPED_TEST_P(AudioSystemTestTemplate,
GetInputDeviceDescriptionsNoInputDevices) {
this->output_device_descriptions_.emplace_back(
"output_device_name", "output_device_id", "group_id");
EXPECT_EQ(0, static_cast<int>(this->input_device_descriptions_.size()));
EXPECT_EQ(1, static_cast<int>(this->output_device_descriptions_.size()));
base::RunLoop wait_loop;
this->audio_system()->GetDeviceDescriptions(
true, this->expectations_.GetDeviceDescriptionsCallback(
FROM_HERE, wait_loop.QuitClosure(),
this->input_device_descriptions_));
wait_loop.Run();
}
TYPED_TEST_P(AudioSystemTestTemplate, GetInputDeviceDescriptions) {
this->output_device_descriptions_.emplace_back(
"output_device_name", "output_device_id", "group_id");
this->input_device_descriptions_.emplace_back(
"input_device_name1", "input_device_id1", "group_id1");
this->input_device_descriptions_.emplace_back(
"input_device_name2", "input_device_id2", "group_id2");
EXPECT_EQ(2, static_cast<int>(this->input_device_descriptions_.size()));
EXPECT_EQ(1, static_cast<int>(this->output_device_descriptions_.size()));
base::RunLoop wait_loop;
this->audio_system()->GetDeviceDescriptions(
true, this->expectations_.GetDeviceDescriptionsCallback(
FROM_HERE, wait_loop.QuitClosure(),
this->input_device_descriptions_));
wait_loop.Run();
}
TYPED_TEST_P(AudioSystemTestTemplate,
GetOutputDeviceDescriptionsNoInputDevices) {
this->input_device_descriptions_.emplace_back("input_device_name",
"input_device_id", "group_id");
EXPECT_EQ(0, static_cast<int>(this->output_device_descriptions_.size()));
EXPECT_EQ(1, static_cast<int>(this->input_device_descriptions_.size()));
base::RunLoop wait_loop;
this->audio_system()->GetDeviceDescriptions(
false, this->expectations_.GetDeviceDescriptionsCallback(
FROM_HERE, wait_loop.QuitClosure(),
this->output_device_descriptions_));
wait_loop.Run();
}
TYPED_TEST_P(AudioSystemTestTemplate, GetOutputDeviceDescriptions) {
this->input_device_descriptions_.emplace_back("input_device_name",
"input_device_id", "group_id");
this->output_device_descriptions_.emplace_back(
"output_device_name1", "output_device_id1", "group_id1");
this->output_device_descriptions_.emplace_back(
"output_device_name2", "output_device_id2", "group_id2");
EXPECT_EQ(2, static_cast<int>(this->output_device_descriptions_.size()));
EXPECT_EQ(1, static_cast<int>(this->input_device_descriptions_.size()));
base::RunLoop wait_loop;
this->audio_system()->GetDeviceDescriptions(
false, this->expectations_.GetDeviceDescriptionsCallback(
FROM_HERE, wait_loop.QuitClosure(),
this->output_device_descriptions_));
wait_loop.Run();
}
TYPED_TEST_P(AudioSystemTestTemplate, GetAssociatedOutputDeviceID) {
const std::string associated_id("associated_id");
this->audio_manager()->SetAssociatedOutputDeviceIDCallback(
base::BindRepeating([](const std::string& result, const std::string&)
-> std::string { return result; },
associated_id));
base::RunLoop wait_loop;
this->audio_system()->GetAssociatedOutputDeviceID(
std::string(), this->expectations_.GetDeviceIdCallback(
FROM_HERE, wait_loop.QuitClosure(), associated_id));
wait_loop.Run();
}
TYPED_TEST_P(AudioSystemTestTemplate, GetInputDeviceInfoNoAssociation) {
base::RunLoop wait_loop;
this->audio_system()->GetInputDeviceInfo(
"non-default-device-id",
this->expectations_.GetInputDeviceInfoCallback(
FROM_HERE, wait_loop.QuitClosure(), this->input_params_,
absl::optional<std::string>()));
wait_loop.Run();
}
TYPED_TEST_P(AudioSystemTestTemplate, GetInputDeviceInfoWithAssociation) {
const std::string associated_id("associated_id");
this->audio_manager()->SetAssociatedOutputDeviceIDCallback(
base::BindRepeating([](const std::string& result, const std::string&)
-> std::string { return result; },
associated_id));
base::RunLoop wait_loop;
this->audio_system()->GetInputDeviceInfo(
"non-default-device-id", this->expectations_.GetInputDeviceInfoCallback(
FROM_HERE, wait_loop.QuitClosure(),
this->input_params_, associated_id));
wait_loop.Run();
}
REGISTER_TYPED_TEST_SUITE_P(
AudioSystemTestTemplate,
GetInputStreamParametersNormal,
GetInputStreamParametersNoDevice,
GetOutputStreamParameters,
GetDefaultOutputStreamParameters,
GetOutputStreamParametersForDefaultDeviceNoDevices,
GetOutputStreamParametersForNonDefaultDeviceNoDevices,
HasInputDevices,
HasNoInputDevices,
HasOutputDevices,
HasNoOutputDevices,
GetInputDeviceDescriptionsNoInputDevices,
GetInputDeviceDescriptions,
GetOutputDeviceDescriptionsNoInputDevices,
GetOutputDeviceDescriptions,
GetAssociatedOutputDeviceID,
GetInputDeviceInfoNoAssociation,
GetInputDeviceInfoWithAssociation);
} // namespace media
#endif // MEDIA_AUDIO_AUDIO_SYSTEM_TEST_UTIL_H_