Audio HAL: Align V2 and V4 VTS
It was thought that the V2 VTS were not going to be supported after V4
VTS were created. Thus a large portion of the code was copy paste and
modified.
That assumption ended up wrong as a lot of OEM reported bugs that needed
to be fixed in both versions.
As a result align the code of both version VTS as much as possible.
The code will be merged in a follow up patch.
Bug: 118203066
Test: compile
Change-Id: I994232db237b5d7c52e7d796f199ab3c6eec21f4
Signed-off-by: Kevin Rocard <krocard@google.com>
diff --git a/audio/common/all-versions/default/include/common/all-versions/default/HidlUtils.impl.h b/audio/common/all-versions/default/include/common/all-versions/default/HidlUtils.impl.h
index 632e816..03b50b5 100644
--- a/audio/common/all-versions/default/include/common/all-versions/default/HidlUtils.impl.h
+++ b/audio/common/all-versions/default/include/common/all-versions/default/HidlUtils.impl.h
@@ -33,7 +33,7 @@
using ::android::hardware::audio::common::AUDIO_HAL_VERSION::AudioStreamType;
using ::android::hardware::audio::common::AUDIO_HAL_VERSION::AudioUsage;
-using ::android::hardware::audio::common::utils::mkEnumConverter;
+using ::android::hardware::audio::common::utils::EnumBitfield;
namespace android {
namespace hardware {
@@ -43,7 +43,7 @@
void HidlUtils::audioConfigFromHal(const audio_config_t& halConfig, AudioConfig* config) {
config->sampleRateHz = halConfig.sample_rate;
- config->channelMask = mkEnumConverter<AudioChannelMask>(halConfig.channel_mask);
+ config->channelMask = EnumBitfield<AudioChannelMask>(halConfig.channel_mask);
config->format = AudioFormat(halConfig.format);
audioOffloadInfoFromHal(halConfig.offload_info, &config->offloadInfo);
config->frameCount = halConfig.frame_count;
@@ -61,8 +61,8 @@
void HidlUtils::audioGainConfigFromHal(const struct audio_gain_config& halConfig,
AudioGainConfig* config) {
config->index = halConfig.index;
- config->mode = mkEnumConverter<AudioGainMode>(halConfig.mode);
- config->channelMask = mkEnumConverter<AudioChannelMask>(halConfig.channel_mask);
+ config->mode = EnumBitfield<AudioGainMode>(halConfig.mode);
+ config->channelMask = EnumBitfield<AudioChannelMask>(halConfig.channel_mask);
for (size_t i = 0; i < sizeof(audio_channel_mask_t) * 8; ++i) {
config->values[i] = halConfig.values[i];
}
@@ -82,8 +82,8 @@
}
void HidlUtils::audioGainFromHal(const struct audio_gain& halGain, AudioGain* gain) {
- gain->mode = mkEnumConverter<AudioGainMode>(halGain.mode);
- gain->channelMask = mkEnumConverter<AudioChannelMask>(halGain.channel_mask);
+ gain->mode = EnumBitfield<AudioGainMode>(halGain.mode);
+ gain->channelMask = EnumBitfield<AudioChannelMask>(halGain.channel_mask);
gain->minValue = halGain.min_value;
gain->maxValue = halGain.max_value;
gain->defaultValue = halGain.default_value;
@@ -122,7 +122,7 @@
void HidlUtils::audioOffloadInfoFromHal(const audio_offload_info_t& halOffload,
AudioOffloadInfo* offload) {
offload->sampleRateHz = halOffload.sample_rate;
- offload->channelMask = mkEnumConverter<AudioChannelMask>(halOffload.channel_mask);
+ offload->channelMask = EnumBitfield<AudioChannelMask>(halOffload.channel_mask);
offload->format = AudioFormat(halOffload.format);
offload->streamType = AudioStreamType(halOffload.stream_type);
offload->bitRatePerSecond = halOffload.bit_rate;
@@ -155,9 +155,9 @@
config->id = halConfig.id;
config->role = AudioPortRole(halConfig.role);
config->type = AudioPortType(halConfig.type);
- config->configMask = mkEnumConverter<AudioPortConfigMask>(halConfig.config_mask);
+ config->configMask = EnumBitfield<AudioPortConfigMask>(halConfig.config_mask);
config->sampleRateHz = halConfig.sample_rate;
- config->channelMask = mkEnumConverter<AudioChannelMask>(halConfig.channel_mask);
+ config->channelMask = EnumBitfield<AudioChannelMask>(halConfig.channel_mask);
config->format = AudioFormat(halConfig.format);
audioGainConfigFromHal(halConfig.gain, &config->gain);
switch (halConfig.type) {
@@ -257,7 +257,7 @@
}
port->channelMasks.resize(halPort.num_channel_masks);
for (size_t i = 0; i < halPort.num_channel_masks; ++i) {
- port->channelMasks[i] = mkEnumConverter<AudioChannelMask>(halPort.channel_masks[i]);
+ port->channelMasks[i] = EnumBitfield<AudioChannelMask>(halPort.channel_masks[i]);
}
port->formats.resize(halPort.num_formats);
for (size_t i = 0; i < halPort.num_formats; ++i) {
diff --git a/audio/common/all-versions/util/include/common/all-versions/VersionUtils.h b/audio/common/all-versions/util/include/common/all-versions/VersionUtils.h
index 70c3d56..3b5c0fb 100644
--- a/audio/common/all-versions/util/include/common/all-versions/VersionUtils.h
+++ b/audio/common/all-versions/util/include/common/all-versions/VersionUtils.h
@@ -26,36 +26,31 @@
namespace common {
namespace utils {
-/** Similar to static_cast but also casts to hidl_bitfield depending on
- * return type inference (emulated through user-define conversion).
- */
-template <class Source, class Destination = Source>
-class EnumConverter {
+/** Converting between a bitfield or itself. */
+template <class Enum>
+class EnumBitfield {
public:
- static_assert(std::is_enum<Source>::value || std::is_enum<Destination>::value,
- "Source or destination should be an enum");
+ using Bitfield = ::android::hardware::hidl_bitfield<Enum>;
- explicit EnumConverter(Source source) : mSource(source) {}
+ EnumBitfield(const EnumBitfield&) = default;
+ explicit EnumBitfield(Enum value) : mValue(value) {}
+ explicit EnumBitfield(Bitfield value) : EnumBitfield(static_cast<Enum>(value)) {}
- operator Destination() const { return static_cast<Destination>(mSource); }
+ EnumBitfield& operator=(const EnumBitfield&) = default;
+ EnumBitfield& operator=(Enum value) { return *this = EnumBitfield{value}; }
+ EnumBitfield& operator=(Bitfield value) { return *this = EnumBitfield{value}; }
- template <class = std::enable_if_t<std::is_enum<Destination>::value>>
- operator ::android::hardware::hidl_bitfield<Destination>() {
- return static_cast<std::underlying_type_t<Destination>>(mSource);
- }
+ operator Enum() const { return mValue; }
+ operator Bitfield() const { return static_cast<Bitfield>(mValue); }
private:
- const Source mSource;
+ Enum mValue;
};
-template <class Destination, class Source>
-auto mkEnumConverter(Source source) {
- return EnumConverter<Source, Destination>{source};
-}
-/** Allows converting an enum to its bitfield or itself. */
+/** ATD way to create a EnumBitfield. */
template <class Enum>
-EnumConverter<Enum> mkBitfield(Enum value) {
- return EnumConverter<Enum>{value};
+EnumBitfield<Enum> mkEnumBitfield(Enum value) {
+ return EnumBitfield<Enum>{value};
}
} // namespace utils
diff --git a/audio/core/2.0/vts/functional/Android.bp b/audio/core/2.0/vts/functional/Android.bp
index cfa637b..ce6e8a2 100644
--- a/audio/core/2.0/vts/functional/Android.bp
+++ b/audio/core/2.0/vts/functional/Android.bp
@@ -29,5 +29,11 @@
"libicuuc_stubdata",
"libxml2",
],
+ shared_libs: [
+ "libfmq",
+ ],
+ header_libs: [
+ "android.hardware.audio.common.util@all-versions",
+ ],
test_suites: ["general-tests"],
}
diff --git a/audio/core/2.0/vts/functional/AudioPrimaryHidlHalTest.cpp b/audio/core/2.0/vts/functional/AudioPrimaryHidlHalTest.cpp
index 01544fe..2f4c34d 100644
--- a/audio/core/2.0/vts/functional/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/2.0/vts/functional/AudioPrimaryHidlHalTest.cpp
@@ -22,12 +22,15 @@
#include <cstdio>
#include <initializer_list>
#include <limits>
+#include <list>
#include <string>
#include <vector>
#include <fcntl.h>
#include <unistd.h>
+#include <hwbinder/IPCThreadState.h>
+
#include <VtsHalHidlTargetTestBase.h>
#include <android-base/logging.h>
@@ -37,6 +40,10 @@
#include <android/hardware/audio/2.0/IPrimaryDevice.h>
#include <android/hardware/audio/2.0/types.h>
#include <android/hardware/audio/common/2.0/types.h>
+#include <fmq/EventFlag.h>
+#include <fmq/MessageQueue.h>
+
+#include <common/all-versions/VersionUtils.h>
#include "utility/AssertOk.h"
#include "utility/Documentation.h"
@@ -46,14 +53,21 @@
#include "utility/ReturnIn.h"
using std::initializer_list;
+using std::list;
using std::string;
using std::to_string;
using std::vector;
using ::android::sp;
+using ::android::hardware::EventFlag;
+using ::android::hardware::hidl_bitfield;
+using ::android::hardware::hidl_enum_range;
using ::android::hardware::hidl_handle;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
+using ::android::hardware::IPCThreadState;
+using ::android::hardware::kSynchronizedReadWrite;
+using ::android::hardware::MessageQueue;
using ::android::hardware::MQDescriptorSync;
using ::android::hardware::Return;
using ::android::hardware::audio::V2_0::AudioDrain;
@@ -64,14 +78,17 @@
using ::android::hardware::audio::V2_0::IDevicesFactory;
using ::android::hardware::audio::V2_0::IStream;
using ::android::hardware::audio::V2_0::IStreamIn;
+using ::android::hardware::audio::V2_0::MessageQueueFlagBits;
using ::android::hardware::audio::V2_0::TimeSpec;
using ReadParameters = ::android::hardware::audio::V2_0::IStreamIn::ReadParameters;
using ReadStatus = ::android::hardware::audio::V2_0::IStreamIn::ReadStatus;
+using ::android::hardware::audio::common::utils::mkEnumBitfield;
using ::android::hardware::audio::common::V2_0::AudioChannelMask;
using ::android::hardware::audio::common::V2_0::AudioConfig;
using ::android::hardware::audio::common::V2_0::AudioDevice;
using ::android::hardware::audio::common::V2_0::AudioFormat;
using ::android::hardware::audio::common::V2_0::AudioHandleConsts;
+using ::android::hardware::audio::common::V2_0::AudioHwSync;
using ::android::hardware::audio::common::V2_0::AudioInputFlag;
using ::android::hardware::audio::common::V2_0::AudioIoHandle;
using ::android::hardware::audio::common::V2_0::AudioMode;
@@ -88,6 +105,15 @@
using namespace ::android::hardware::audio::common::test::utility;
+// Typical accepted results from interface methods
+static auto okOrNotSupported = {Result::OK, Result::NOT_SUPPORTED};
+static auto okOrNotSupportedOrInvalidArgs = {Result::OK, Result::NOT_SUPPORTED,
+ Result::INVALID_ARGUMENTS};
+static auto okOrInvalidStateOrNotSupported = {Result::OK, Result::INVALID_STATE,
+ Result::NOT_SUPPORTED};
+static auto invalidArgsOrNotSupported = {Result::INVALID_ARGUMENTS, Result::NOT_SUPPORTED};
+static auto invalidStateOrNotSupported = {Result::INVALID_STATE, Result::NOT_SUPPORTED};
+
class AudioHidlTestEnvironment : public ::Environment {
public:
virtual void registerTestServices() override { registerTestService<IDevicesFactory>(); }
@@ -127,15 +153,16 @@
sp<IDevicesFactory> AudioHidlTest::devicesFactory;
TEST_F(AudioHidlTest, GetAudioDevicesFactoryService) {
- doc::test("test the getService (called in SetUp)");
+ doc::test("Test the getService (called in SetUp)");
}
TEST_F(AudioHidlTest, OpenDeviceInvalidParameter) {
- doc::test("test passing an invalid parameter to openDevice");
- IDevicesFactory::Result result;
+ doc::test("Test passing an invalid parameter to openDevice");
+ Result result;
sp<IDevice> device;
- ASSERT_OK(devicesFactory->openDevice(IDevicesFactory::Device(-1), returnIn(result, device)));
- ASSERT_EQ(IDevicesFactory::Result::INVALID_ARGUMENTS, result);
+ auto invalidDevice = IDevicesFactory::Device(-1);
+ ASSERT_OK(devicesFactory->openDevice(invalidDevice, returnIn(result, device)));
+ ASSERT_EQ(Result::INVALID_ARGUMENTS, result);
ASSERT_TRUE(device == nullptr);
}
@@ -151,22 +178,27 @@
ASSERT_NO_FATAL_FAILURE(AudioHidlTest::SetUp()); // setup base
if (device == nullptr) {
- IDevicesFactory::Result result;
- sp<IDevice> baseDevice;
- ASSERT_OK(devicesFactory->openDevice(IDevicesFactory::Device::PRIMARY,
- returnIn(result, baseDevice)));
- ASSERT_OK(result);
- ASSERT_TRUE(baseDevice != nullptr);
-
- environment->registerTearDown([] { device.clear(); });
- device = IPrimaryDevice::castFrom(baseDevice);
+ initPrimaryDevice();
ASSERT_TRUE(device != nullptr);
+ environment->registerTearDown([] { device.clear(); });
}
}
protected:
// Cache the device opening to speed up each test by ~0.5s
static sp<IPrimaryDevice> device;
+
+ private:
+ void initPrimaryDevice() {
+ Result result;
+ sp<IDevice> baseDevice;
+ ASSERT_OK(devicesFactory->openDevice(IDevicesFactory::Device::PRIMARY,
+ returnIn(result, baseDevice)));
+ ASSERT_OK(result);
+ ASSERT_TRUE(baseDevice != nullptr);
+
+ device = IPrimaryDevice::castFrom(baseDevice);
+ }
};
sp<IPrimaryDevice> AudioPrimaryHidlTest::device;
@@ -186,53 +218,59 @@
template <class Property>
class AccessorPrimaryHidlTest : public AudioPrimaryHidlTest {
protected:
- /** Test a property getter and setter. */
- template <class Getter, class Setter>
- void testAccessors(const string& propertyName, const vector<Property>& valuesToTest,
- Setter setter, Getter getter, const vector<Property>& invalidValues = {}) {
- Property initialValue; // Save initial value to restore it at the end
- // of the test
- ASSERT_OK((device.get()->*getter)(returnIn(res, initialValue)));
- ASSERT_OK(res);
+ enum Optionality { REQUIRED, OPTIONAL };
+ struct Initial { // Initial property value
+ Initial(Property value, Optionality check = REQUIRED) : value(value), check(check) {}
+ Property value;
+ Optionality check; // If this initial value should be checked
+ };
+ /** Test a property getter and setter.
+ * The getter and/or the setter may return NOT_SUPPORTED if optionality == OPTIONAL.
+ */
+ template <Optionality optionality = REQUIRED, class Getter, class Setter>
+ void testAccessors(const string& propertyName, const Initial expectedInitial,
+ list<Property> valuesToTest, Setter setter, Getter getter,
+ const vector<Property>& invalidValues = {}) {
+ const auto expectedResults = {Result::OK,
+ optionality == OPTIONAL ? Result::NOT_SUPPORTED : Result::OK};
+ Property initialValue = expectedInitial.value;
+ ASSERT_OK((device.get()->*getter)(returnIn(res, initialValue)));
+ ASSERT_RESULT(expectedResults, res);
+ if (res == Result::OK && expectedInitial.check == REQUIRED) {
+ EXPECT_EQ(expectedInitial.value, initialValue);
+ }
+
+ valuesToTest.push_front(expectedInitial.value);
+ valuesToTest.push_back(initialValue);
for (Property setValue : valuesToTest) {
SCOPED_TRACE("Test " + propertyName + " getter and setter for " +
testing::PrintToString(setValue));
- ASSERT_OK((device.get()->*setter)(setValue));
+ auto ret = (device.get()->*setter)(setValue);
+ ASSERT_RESULT(expectedResults, ret);
+ if (ret == Result::NOT_SUPPORTED) {
+ doc::partialTest(propertyName + " setter is not supported");
+ break;
+ }
Property getValue;
// Make sure the getter returns the same value just set
ASSERT_OK((device.get()->*getter)(returnIn(res, getValue)));
- ASSERT_OK(res);
+ ASSERT_RESULT(expectedResults, res);
+ if (res == Result::NOT_SUPPORTED) {
+ doc::partialTest(propertyName + " getter is not supported");
+ continue;
+ }
EXPECT_EQ(setValue, getValue);
}
for (Property invalidValue : invalidValues) {
SCOPED_TRACE("Try to set " + propertyName + " with the invalid value " +
testing::PrintToString(invalidValue));
- EXPECT_RESULT(Result::INVALID_ARGUMENTS, (device.get()->*setter)(invalidValue));
+ EXPECT_RESULT(invalidArgsOrNotSupported, (device.get()->*setter)(invalidValue));
}
- ASSERT_OK((device.get()->*setter)(initialValue)); // restore initial value
- }
-
- /** Test the getter and setter of an optional feature. */
- template <class Getter, class Setter>
- void testOptionalAccessors(const string& propertyName, const vector<Property>& valuesToTest,
- Setter setter, Getter getter,
- const vector<Property>& invalidValues = {}) {
- doc::test("Test the optional " + propertyName + " getters and setter");
- {
- SCOPED_TRACE("Test feature support by calling the getter");
- Property initialValue;
- ASSERT_OK((device.get()->*getter)(returnIn(res, initialValue)));
- if (res == Result::NOT_SUPPORTED) {
- doc::partialTest(propertyName + " getter is not supported");
- return;
- }
- ASSERT_OK(res); // If it is supported it must succeed
- }
- // The feature is supported, test it
- testAccessors(propertyName, valuesToTest, setter, getter, invalidValues);
+ // Restore initial value
+ EXPECT_RESULT(expectedResults, (device.get()->*setter)(initialValue));
}
};
@@ -240,24 +278,22 @@
TEST_F(BoolAccessorPrimaryHidlTest, MicMuteTest) {
doc::test("Check that the mic can be muted and unmuted");
- testAccessors("mic mute", {true, false, true}, &IDevice::setMicMute, &IDevice::getMicMute);
+ testAccessors("mic mute", Initial{false}, {true}, &IDevice::setMicMute, &IDevice::getMicMute);
// TODO: check that the mic is really muted (all sample are 0)
}
TEST_F(BoolAccessorPrimaryHidlTest, MasterMuteTest) {
- doc::test(
- "If master mute is supported, try to mute and unmute the master "
- "output");
- testOptionalAccessors("master mute", {true, false, true}, &IDevice::setMasterMute,
- &IDevice::getMasterMute);
+ doc::test("If master mute is supported, try to mute and unmute the master output");
+ testAccessors<OPTIONAL>("master mute", Initial{false}, {true}, &IDevice::setMasterMute,
+ &IDevice::getMasterMute);
// TODO: check that the master volume is really muted
}
using FloatAccessorPrimaryHidlTest = AccessorPrimaryHidlTest<float>;
TEST_F(FloatAccessorPrimaryHidlTest, MasterVolumeTest) {
doc::test("Test the master volume if supported");
- testOptionalAccessors(
- "master volume", {0, 0.5, 1}, &IDevice::setMasterVolume, &IDevice::getMasterVolume,
+ testAccessors<OPTIONAL>(
+ "master volume", Initial{1}, {0, 0.5}, &IDevice::setMasterVolume, &IDevice::getMasterVolume,
{-0.1, 1.1, NAN, INFINITY, -INFINITY, 1 + std::numeric_limits<float>::epsilon()});
// TODO: check that the master volume is really changed
}
@@ -337,7 +373,7 @@
for (auto format : formats) {
AudioConfig config{};
// leave offloadInfo to 0
- config.channelMask = channelMask;
+ config.channelMask = mkEnumBitfield(channelMask);
config.sampleRateHz = sampleRate;
config.format = format;
// FIXME: leave frameCount to 0 ?
@@ -358,10 +394,10 @@
const AudioConfig& config = info.param;
return to_string(info.index) + "__" + to_string(config.sampleRateHz) + "_" +
// "MONO" is more clear than "FRONT_LEFT"
- ((config.channelMask == AudioChannelMask::OUT_MONO ||
- config.channelMask == AudioChannelMask::IN_MONO)
+ ((config.channelMask == mkEnumBitfield(AudioChannelMask::OUT_MONO) ||
+ config.channelMask == mkEnumBitfield(AudioChannelMask::IN_MONO))
? "MONO"
- : toString(config.channelMask));
+ : ::testing::PrintToString(config.channelMask));
}
//////////////////////////////////////////////////////////////////////////////
@@ -433,11 +469,7 @@
TEST_F(AudioPrimaryHidlTest, setScreenState) {
doc::test("Check that the hal can receive the screen state");
for (bool turnedOn : {false, true, true, false, false}) {
- auto ret = device->setScreenState(turnedOn);
- ASSERT_IS_OK(ret);
- Result result = ret;
- auto okOrNotSupported = {Result::OK, Result::NOT_SUPPORTED};
- ASSERT_RESULT(okOrNotSupported, result);
+ ASSERT_RESULT(okOrNotSupported, device->setScreenState(turnedOn));
}
}
@@ -445,14 +477,26 @@
//////////////////////////// {get,set}Parameters /////////////////////////////
//////////////////////////////////////////////////////////////////////////////
+struct Parameters {
+ template <class T, class ReturnIn>
+ static auto get(T t, hidl_vec<hidl_string> keys, ReturnIn returnIn) {
+ return t->getParameters(keys, returnIn);
+ }
+ template <class T>
+ static auto set(T t, hidl_vec<ParameterValue> values) {
+ return t->setParameters(values);
+ }
+};
+
TEST_F(AudioPrimaryHidlTest, getParameters) {
doc::test("Check that the hal can set and get parameters");
+ hidl_vec<ParameterValue> context;
hidl_vec<hidl_string> keys;
hidl_vec<ParameterValue> values;
- ASSERT_OK(device->getParameters(keys, returnIn(res, values)));
- ASSERT_OK(device->setParameters(values));
+ ASSERT_OK(Parameters::get(device, keys, returnIn(res, values)));
+ ASSERT_OK(Parameters::set(device, values));
values.resize(0);
- ASSERT_OK(device->setParameters(values));
+ ASSERT_OK(Parameters::set(device, values));
}
//////////////////////////////////////////////////////////////////////////////
@@ -493,14 +537,19 @@
EXPECT_EQ(0, close(fds[1])) << errno;
}
+template <class T>
+auto dump(T t, hidl_handle handle) {
+ return t->debugDump(handle);
+}
+
TEST_F(AudioPrimaryHidlTest, DebugDump) {
doc::test("Check that the hal can dump its state without error");
- testDebugDump([](const auto& handle) { return device->debugDump(handle); });
+ testDebugDump([](const auto& handle) { return dump(device, handle); });
}
TEST_F(AudioPrimaryHidlTest, DebugDumpInvalidArguments) {
doc::test("Check that the hal dump doesn't crash on invalid arguments");
- ASSERT_OK(device->debugDump(hidl_handle()));
+ ASSERT_OK(dump(device, hidl_handle()));
}
//////////////////////////////////////////////////////////////////////////////
@@ -569,7 +618,8 @@
ASSERT_NO_FATAL_FAILURE(OpenStreamTest::SetUp()); // setup base
address.device = AudioDevice::OUT_DEFAULT;
const AudioConfig& config = GetParam();
- AudioOutputFlag flags = AudioOutputFlag::NONE; // TODO: test all flag combination
+ // TODO: test all flag combination
+ auto flags = mkEnumBitfield(AudioOutputFlag::NONE);
testOpen(
[&](AudioIoHandle handle, AudioConfig config, auto cb) {
return device->openOutputStream(handle, address, config, flags, cb);
@@ -604,14 +654,17 @@
ASSERT_NO_FATAL_FAILURE(OpenStreamTest::SetUp()); // setup base
address.device = AudioDevice::IN_DEFAULT;
const AudioConfig& config = GetParam();
- AudioInputFlag flags = AudioInputFlag::NONE; // TODO: test all flag combination
- AudioSource source = AudioSource::DEFAULT; // TODO: test all flag combination
+ // TODO: test all supported flags and source
+ auto flags = mkEnumBitfield(AudioInputFlag::NONE);
testOpen(
[&](AudioIoHandle handle, AudioConfig config, auto cb) {
- return device->openInputStream(handle, address, config, flags, source, cb);
+ return device->openInputStream(handle, address, config, flags, initMetadata, cb);
},
config);
}
+
+ protected:
+ const AudioSource initMetadata = AudioSource::DEFAULT;
};
TEST_P(InputStreamTest, OpenInputStreamTest) {
@@ -682,27 +735,26 @@
template <class Property, class CapabilityGetter>
static void testCapabilityGetter(const string& name, IStream* stream,
- CapabilityGetter capablityGetter,
+ CapabilityGetter capabilityGetter,
Return<Property> (IStream::*getter)(),
Return<Result> (IStream::*setter)(Property),
bool currentMustBeSupported = true) {
hidl_vec<Property> capabilities;
- ASSERT_OK((stream->*capablityGetter)(returnIn(capabilities)));
- if (capabilities.size() == 0) {
- // The default hal should probably return a NOT_SUPPORTED if the hal
- // does not expose
- // capability retrieval. For now it returns an empty list if not
- // implemented
+ auto ret = capabilityGetter(stream, capabilities);
+ ASSERT_RESULT(okOrNotSupported, ret);
+ bool notSupported = ret == Result::NOT_SUPPORTED;
+ if (notSupported) {
doc::partialTest(name + " is not supported");
return;
};
if (currentMustBeSupported) {
+ ASSERT_NE(0U, capabilities.size()) << name << " must not return an empty list";
Property currentValue = extract((stream->*getter)());
- EXPECT_NE(std::find(capabilities.begin(), capabilities.end(), currentValue),
- capabilities.end())
- << "current " << name << " is not in the list of the supported ones "
- << toString(capabilities);
+ EXPECT_TRUE(std::find(capabilities.begin(), capabilities.end(), currentValue) !=
+ capabilities.end())
+ << "value returned by " << name << "() = " << testing::PrintToString(currentValue)
+ << " is not in the list of the supported ones " << toString(capabilities);
}
// Check that all declared supported values are indeed supported
@@ -718,9 +770,36 @@
}
}
+// The default hal should probably return a NOT_SUPPORTED if the hal
+// does not expose
+// capability retrieval. For now it returns an empty list if not
+// implemented
+struct GetSupported {
+ template <class Vec>
+ static Result convertToResult(const Vec& vec) {
+ return vec.size() == 0 ? Result::NOT_SUPPORTED : Result::OK;
+ }
+
+ static Result sampleRates(IStream* stream, hidl_vec<uint32_t>& rates) {
+ EXPECT_OK(stream->getSupportedSampleRates(returnIn(rates)));
+ return convertToResult(rates);
+ }
+
+ static Result channelMasks(IStream* stream, hidl_vec<AudioChannelMask>& channels) {
+ EXPECT_OK(stream->getSupportedChannelMasks(returnIn(channels)));
+ return convertToResult(channels);
+ }
+
+ static Result formats(IStream* stream, hidl_vec<AudioFormat>& capabilities) {
+ EXPECT_OK(stream->getSupportedFormats(returnIn(capabilities)));
+ // TODO: this should be an optional function
+ return Result::OK;
+ }
+};
+
TEST_IO_STREAM(SupportedSampleRate, "Check that the stream sample rate is declared as supported",
testCapabilityGetter("getSupportedSampleRate", stream.get(),
- &IStream::getSupportedSampleRates, &IStream::getSampleRate,
+ &GetSupported::sampleRates, &IStream::getSampleRate,
&IStream::setSampleRate,
// getSupportedSampleRate returns the native sampling rates,
// (the sampling rates that can be played without resampling)
@@ -729,13 +808,12 @@
TEST_IO_STREAM(SupportedChannelMask, "Check that the stream channel mask is declared as supported",
testCapabilityGetter("getSupportedChannelMask", stream.get(),
- &IStream::getSupportedChannelMasks, &IStream::getChannelMask,
+ &GetSupported::channelMasks, &IStream::getChannelMask,
&IStream::setChannelMask))
TEST_IO_STREAM(SupportedFormat, "Check that the stream format is declared as supported",
- testCapabilityGetter("getSupportedFormat", stream.get(),
- &IStream::getSupportedFormats, &IStream::getFormat,
- &IStream::setFormat))
+ testCapabilityGetter("getSupportedFormat", stream.get(), &GetSupported::formats,
+ &IStream::getFormat, &IStream::setFormat))
static void testGetDevice(IStream* stream, AudioDevice expectedDevice) {
// Unfortunately the interface does not allow the implementation to return
@@ -768,7 +846,7 @@
static void testGetAudioProperties(IStream* stream, AudioConfig expectedConfig) {
uint32_t sampleRateHz;
- AudioChannelMask mask;
+ auto mask = mkEnumBitfield<AudioChannelMask>({});
AudioFormat format;
stream->getAudioProperties(returnIn(sampleRateHz, mask, format));
@@ -784,6 +862,9 @@
"Check that the stream audio properties == the ones it was opened with",
testGetAudioProperties(stream.get(), audioConfig))
+TEST_IO_STREAM(SetHwAvSync, "Try to set hardware sync to an invalid value",
+ ASSERT_RESULT(okOrNotSupportedOrInvalidArgs, stream->setHwAvSync(666)))
+
static void testConnectedState(IStream* stream) {
DeviceAddress address = {};
using AD = AudioDevice;
@@ -799,18 +880,13 @@
"deconnection",
testConnectedState(stream.get()))
-static auto invalidArgsOrNotSupportedOrOK = {Result::INVALID_ARGUMENTS, Result::NOT_SUPPORTED,
- Result::OK};
-TEST_IO_STREAM(SetHwAvSync, "Try to set hardware sync to an invalid value",
- ASSERT_RESULT(invalidArgsOrNotSupportedOrOK, stream->setHwAvSync(666)))
-
TEST_IO_STREAM(GetHwAvSync, "Get hardware sync can not fail", ASSERT_IS_OK(device->getHwAvSync()));
static void checkGetNoParameter(IStream* stream, hidl_vec<hidl_string> keys,
initializer_list<Result> expectedResults) {
hidl_vec<ParameterValue> parameters;
Result res;
- ASSERT_OK(stream->getParameters(keys, returnIn(res, parameters)));
+ ASSERT_OK(Parameters::get(stream, keys, returnIn(res, parameters)));
ASSERT_RESULT(expectedResults, res);
if (res == Result::OK) {
for (auto& parameter : parameters) {
@@ -831,22 +907,22 @@
{Result::NOT_SUPPORTED}))
TEST_IO_STREAM(setEmptySetParameter, "Set the values of an empty set of parameters",
- ASSERT_RESULT(Result::OK, stream->setParameters({})))
+ ASSERT_RESULT(Result::OK, Parameters::set(stream, {})))
TEST_IO_STREAM(setNonExistingParameter, "Set the values of an non existing parameter",
// Unfortunately, the set_parameter legacy interface did not return any
// error code when a key is not supported.
// To allow implementation to just wrapped the legacy one, consider OK as a
// valid result for setting a non existing parameter.
- ASSERT_RESULT(invalidArgsOrNotSupportedOrOK,
- stream->setParameters({{"non existing key", "0"}})))
+ ASSERT_RESULT(okOrNotSupportedOrInvalidArgs,
+ Parameters::set(stream, {{"non existing key", "0"}})))
TEST_IO_STREAM(DebugDump, "Check that a stream can dump its state without error",
- testDebugDump([this](const auto& handle) { return stream->debugDump(handle); }))
+ testDebugDump([this](const auto& handle) { return dump(stream, handle); }))
TEST_IO_STREAM(DebugDumpInvalidArguments,
"Check that the stream dump doesn't crash on invalid arguments",
- ASSERT_OK(stream->debugDump(hidl_handle())))
+ ASSERT_OK(dump(stream, hidl_handle())))
//////////////////////////////////////////////////////////////////////////////
////////////////////////////// addRemoveEffect ///////////////////////////////
@@ -866,8 +942,6 @@
TEST_IO_STREAM(standby, "Make sure the stream can be put in stanby",
ASSERT_OK(stream->standby())) // can not fail
-static constexpr auto invalidStateOrNotSupported = {Result::INVALID_STATE, Result::NOT_SUPPORTED};
-
TEST_IO_STREAM(startNoMmap, "Starting a mmaped stream before mapping it should fail",
ASSERT_RESULT(invalidStateOrNotSupported, stream->start()))
@@ -881,7 +955,6 @@
TEST_IO_STREAM(closeTwice, "Make sure a stream can not be closed twice", ASSERT_OK(closeStream());
ASSERT_RESULT(Result::INVALID_STATE, closeStream()))
-static auto invalidArgsOrNotSupported = {Result::INVALID_ARGUMENTS, Result::NOT_SUPPORTED};
static void testCreateTooBigMmapBuffer(IStream* stream) {
MmapBufferInfo info;
Result res;
@@ -988,15 +1061,19 @@
TEST_P(InputStreamTest, getCapturePosition) {
doc::test(
"The capture position of a non prepared stream should not be "
- "retrievable");
+ "retrievable or 0");
uint64_t frames;
uint64_t time;
ASSERT_OK(stream->getCapturePosition(returnIn(res, frames, time)));
- ASSERT_RESULT(invalidStateOrNotSupported, res);
+ ASSERT_RESULT(okOrInvalidStateOrNotSupported, res);
+ if (res == Result::OK) {
+ ASSERT_EQ(0U, frames);
+ ASSERT_LE(0U, time);
+ }
}
//////////////////////////////////////////////////////////////////////////////
-///////////////////////////////// StreamIn ///////////////////////////////////
+///////////////////////////////// StreamOut //////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
TEST_P(OutputStreamTest, getLatency) {
@@ -1103,7 +1180,6 @@
auto res = stream->setCallback(new MockOutCallbacks);
stream->clearCallback(); // try to restore the no callback state, ignore
// any error
- auto okOrNotSupported = {Result::OK, Result::NOT_SUPPORTED};
EXPECT_RESULT(okOrNotSupported, res);
return res.isOk() ? res == Result::OK : false;
}
@@ -1152,7 +1228,7 @@
doc::partialTest("The output stream does not support pause");
return;
}
- ASSERT_RESULT(Result::INVALID_STATE, stream->resume());
+ ASSERT_RESULT(Result::INVALID_STATE, stream->pause());
}
static void testDrain(IStreamOut* stream, AudioDrain type) {
@@ -1223,9 +1299,7 @@
}
TEST_F(AudioPrimaryHidlTest, setMode) {
- doc::test(
- "Make sure setMode always succeeds if mode is valid "
- "and fails otherwise");
+ doc::test("Make sure setMode always succeeds if mode is valid and fails otherwise");
// Test Invalid values
for (AudioMode mode : {AudioMode::INVALID, AudioMode::CURRENT, AudioMode::CNT}) {
SCOPED_TRACE("mode=" + toString(mode));
@@ -1241,29 +1315,30 @@
TEST_F(BoolAccessorPrimaryHidlTest, BtScoNrecEnabled) {
doc::test("Query and set the BT SCO NR&EC state");
- testOptionalAccessors("BtScoNrecEnabled", {true, false, true},
- &IPrimaryDevice::setBtScoNrecEnabled,
- &IPrimaryDevice::getBtScoNrecEnabled);
+ testAccessors<OPTIONAL>("BtScoNrecEnabled", Initial{false, OPTIONAL}, {true},
+ &IPrimaryDevice::setBtScoNrecEnabled,
+ &IPrimaryDevice::getBtScoNrecEnabled);
}
TEST_F(BoolAccessorPrimaryHidlTest, setGetBtScoWidebandEnabled) {
doc::test("Query and set the SCO whideband state");
- testOptionalAccessors("BtScoWideband", {true, false, true},
- &IPrimaryDevice::setBtScoWidebandEnabled,
- &IPrimaryDevice::getBtScoWidebandEnabled);
+ testAccessors<OPTIONAL>("BtScoWideband", Initial{false, OPTIONAL}, {true},
+ &IPrimaryDevice::setBtScoWidebandEnabled,
+ &IPrimaryDevice::getBtScoWidebandEnabled);
}
using TtyModeAccessorPrimaryHidlTest = AccessorPrimaryHidlTest<TtyMode>;
TEST_F(TtyModeAccessorPrimaryHidlTest, setGetTtyMode) {
doc::test("Query and set the TTY mode state");
- testOptionalAccessors("TTY mode", {TtyMode::OFF, TtyMode::HCO, TtyMode::VCO, TtyMode::FULL},
- &IPrimaryDevice::setTtyMode, &IPrimaryDevice::getTtyMode);
+ testAccessors<OPTIONAL>("TTY mode", Initial{TtyMode::OFF},
+ {TtyMode::HCO, TtyMode::VCO, TtyMode::FULL},
+ &IPrimaryDevice::setTtyMode, &IPrimaryDevice::getTtyMode);
}
TEST_F(BoolAccessorPrimaryHidlTest, setGetHac) {
doc::test("Query and set the HAC state");
- testOptionalAccessors("HAC", {true, false, true}, &IPrimaryDevice::setHacEnabled,
- &IPrimaryDevice::getHacEnabled);
+ testAccessors<OPTIONAL>("HAC", Initial{false}, {true}, &IPrimaryDevice::setHacEnabled,
+ &IPrimaryDevice::getHacEnabled);
}
//////////////////////////////////////////////////////////////////////////////
diff --git a/audio/core/2.0/vts/functional/ValidateAudioConfiguration.cpp b/audio/core/2.0/vts/functional/ValidateAudioConfiguration.cpp
index bef0e82..50c5333 100644
--- a/audio/core/2.0/vts/functional/ValidateAudioConfiguration.cpp
+++ b/audio/core/2.0/vts/functional/ValidateAudioConfiguration.cpp
@@ -19,12 +19,19 @@
#include "utility/ValidateXml.h"
+// Stringify the argument.
+#define QUOTE(x) #x
+#define STRINGIFY(x) QUOTE(x)
+
+#define AUDIO_HAL_VERSION V2_0
+
TEST(CheckConfig, audioPolicyConfigurationValidation) {
RecordProperty("description",
"Verify that the audio policy configuration file "
"is valid according to the schema");
std::vector<const char*> locations = {"/odm/etc", "/vendor/etc", "/system/etc"};
- EXPECT_ONE_VALID_XML_MULTIPLE_LOCATIONS("audio_policy_configuration.xml", locations,
- "/data/local/tmp/audio_policy_configuration.xsd");
+ const char* xsd =
+ "/data/local/tmp/audio_policy_configuration_" STRINGIFY(AUDIO_HAL_VERSION) ".xsd";
+ EXPECT_ONE_VALID_XML_MULTIPLE_LOCATIONS("audio_policy_configuration.xml", locations, xsd);
}
diff --git a/audio/core/4.0/vts/functional/AudioPrimaryHidlHalTest.cpp b/audio/core/4.0/vts/functional/AudioPrimaryHidlHalTest.cpp
index d4a5daa..ebf6777 100644
--- a/audio/core/4.0/vts/functional/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/4.0/vts/functional/AudioPrimaryHidlHalTest.cpp
@@ -74,7 +74,6 @@
using ::android::hardware::audio::V4_0::DeviceAddress;
using ::android::hardware::audio::V4_0::IDevice;
using ::android::hardware::audio::V4_0::IPrimaryDevice;
-using Rotation = ::android::hardware::audio::V4_0::IPrimaryDevice::Rotation;
using TtyMode = ::android::hardware::audio::V4_0::IPrimaryDevice::TtyMode;
using ::android::hardware::audio::V4_0::IDevicesFactory;
using ::android::hardware::audio::V4_0::IStream;
@@ -83,10 +82,9 @@
using ::android::hardware::audio::V4_0::TimeSpec;
using ReadParameters = ::android::hardware::audio::V4_0::IStreamIn::ReadParameters;
using ReadStatus = ::android::hardware::audio::V4_0::IStreamIn::ReadStatus;
-using ::android::hardware::audio::common::utils::mkBitfield;
+using ::android::hardware::audio::common::utils::mkEnumBitfield;
using ::android::hardware::audio::common::V4_0::AudioChannelMask;
using ::android::hardware::audio::common::V4_0::AudioConfig;
-using ::android::hardware::audio::common::V4_0::AudioContentType;
using ::android::hardware::audio::common::V4_0::AudioDevice;
using ::android::hardware::audio::common::V4_0::AudioFormat;
using ::android::hardware::audio::common::V4_0::AudioHandleConsts;
@@ -97,15 +95,18 @@
using ::android::hardware::audio::common::V4_0::AudioOffloadInfo;
using ::android::hardware::audio::common::V4_0::AudioOutputFlag;
using ::android::hardware::audio::common::V4_0::AudioSource;
-using ::android::hardware::audio::common::V4_0::AudioUsage;
using ::android::hardware::audio::common::V4_0::ThreadInfo;
using ::android::hardware::audio::V4_0::IStreamOut;
using ::android::hardware::audio::V4_0::IStreamOutCallback;
-using ::android::hardware::audio::V4_0::MicrophoneInfo;
using ::android::hardware::audio::V4_0::MmapBufferInfo;
using ::android::hardware::audio::V4_0::MmapPosition;
using ::android::hardware::audio::V4_0::ParameterValue;
using ::android::hardware::audio::V4_0::Result;
+
+using Rotation = ::android::hardware::audio::V4_0::IPrimaryDevice::Rotation;
+using ::android::hardware::audio::common::V4_0::AudioContentType;
+using ::android::hardware::audio::common::V4_0::AudioUsage;
+using ::android::hardware::audio::V4_0::MicrophoneInfo;
using ::android::hardware::audio::V4_0::SinkMetadata;
using ::android::hardware::audio::V4_0::SourceMetadata;
@@ -166,7 +167,8 @@
doc::test("Test passing an invalid parameter to openDevice");
Result result;
sp<IDevice> device;
- ASSERT_OK(devicesFactory->openDevice("Non existing device", returnIn(result, device)));
+ auto invalidDevice = "Non existing device";
+ ASSERT_OK(devicesFactory->openDevice(invalidDevice, returnIn(result, device)));
ASSERT_EQ(Result::INVALID_ARGUMENTS, result);
ASSERT_TRUE(device == nullptr);
}
@@ -206,11 +208,8 @@
ASSERT_NO_FATAL_FAILURE(AudioHidlTest::SetUp()); // setup base
if (device == nullptr) {
- Result result;
- ASSERT_OK(devicesFactory->openPrimaryDevice(returnIn(result, device)));
- ASSERT_OK(result);
+ initPrimaryDevice();
ASSERT_TRUE(device != nullptr);
-
environment->registerTearDown([] { device.clear(); });
}
}
@@ -218,6 +217,13 @@
protected:
// Cache the device opening to speed up each test by ~0.5s
static sp<IPrimaryDevice> device;
+
+ private:
+ void initPrimaryDevice() {
+ Result result;
+ ASSERT_OK(devicesFactory->openPrimaryDevice(returnIn(result, device)));
+ ASSERT_OK(result);
+ }
};
sp<IPrimaryDevice> AudioPrimaryHidlTest::device;
@@ -392,7 +398,7 @@
for (auto format : formats) {
AudioConfig config{};
// leave offloadInfo to 0
- config.channelMask = mkBitfield(channelMask);
+ config.channelMask = mkEnumBitfield(channelMask);
config.sampleRateHz = sampleRate;
config.format = format;
// FIXME: leave frameCount to 0 ?
@@ -413,8 +419,8 @@
const AudioConfig& config = info.param;
return to_string(info.index) + "__" + to_string(config.sampleRateHz) + "_" +
// "MONO" is more clear than "FRONT_LEFT"
- ((config.channelMask == mkBitfield(AudioChannelMask::OUT_MONO) ||
- config.channelMask == mkBitfield(AudioChannelMask::IN_MONO))
+ ((config.channelMask == mkEnumBitfield(AudioChannelMask::OUT_MONO) ||
+ config.channelMask == mkEnumBitfield(AudioChannelMask::IN_MONO))
? "MONO"
: ::testing::PrintToString(config.channelMask));
}
@@ -496,15 +502,28 @@
//////////////////////////// {get,set}Parameters /////////////////////////////
//////////////////////////////////////////////////////////////////////////////
+struct Parameters {
+ template <class T, class ReturnIn>
+ static auto get(T t, hidl_vec<hidl_string> keys, ReturnIn returnIn) {
+ hidl_vec<ParameterValue> context;
+ return t->getParameters(context, keys, returnIn);
+ }
+ template <class T>
+ static auto set(T t, hidl_vec<ParameterValue> values) {
+ hidl_vec<ParameterValue> context;
+ return t->setParameters(context, values);
+ }
+};
+
TEST_F(AudioPrimaryHidlTest, getParameters) {
doc::test("Check that the hal can set and get parameters");
hidl_vec<ParameterValue> context;
hidl_vec<hidl_string> keys;
hidl_vec<ParameterValue> values;
- ASSERT_OK(device->getParameters(context, keys, returnIn(res, values)));
- ASSERT_OK(device->setParameters(context, values));
+ ASSERT_OK(Parameters::get(device, keys, returnIn(res, values)));
+ ASSERT_OK(Parameters::set(device, values));
values.resize(0);
- ASSERT_OK(device->setParameters(context, values));
+ ASSERT_OK(Parameters::set(device, values));
}
//////////////////////////////////////////////////////////////////////////////
@@ -524,11 +543,11 @@
"and getActiveMicrophones always succeeds when recording from these microphones.");
AudioIoHandle ioHandle = (AudioIoHandle)AudioHandleConsts::AUDIO_IO_HANDLE_NONE;
AudioConfig config{};
- config.channelMask = mkBitfield(AudioChannelMask::IN_MONO);
+ config.channelMask = mkEnumBitfield(AudioChannelMask::IN_MONO);
config.sampleRateHz = 8000;
config.format = AudioFormat::PCM_16_BIT;
auto flags = hidl_bitfield<AudioInputFlag>(AudioInputFlag::NONE);
- const SinkMetadata initialMetadata = {{{AudioSource::MIC, 1 /* gain */}}};
+ const SinkMetadata initMetadata = {{{AudioSource::MIC, 1 /* gain */}}};
EventFlag* efGroup;
for (auto microphone : microphones) {
if (microphone.deviceAddress.device != AudioDevice::IN_BUILTIN_MIC) {
@@ -537,13 +556,13 @@
sp<IStreamIn> stream;
AudioConfig suggestedConfig{};
ASSERT_OK(device->openInputStream(ioHandle, microphone.deviceAddress, config, flags,
- initialMetadata,
+ initMetadata,
returnIn(res, stream, suggestedConfig)));
if (res != Result::OK) {
ASSERT_TRUE(stream == nullptr);
AudioConfig suggestedConfigRetry{};
ASSERT_OK(device->openInputStream(ioHandle, microphone.deviceAddress,
- suggestedConfig, flags, initialMetadata,
+ suggestedConfig, flags, initMetadata,
returnIn(res, stream, suggestedConfigRetry)));
}
ASSERT_OK(res);
@@ -626,14 +645,19 @@
EXPECT_EQ(0, close(fds[1])) << errno;
}
+template <class T>
+auto dump(T t, hidl_handle handle) {
+ return t->debug(handle, {/* options */});
+}
+
TEST_F(AudioPrimaryHidlTest, DebugDump) {
doc::test("Check that the hal can dump its state without error");
- testDebugDump([](const auto& handle) { return device->debug(handle, {/* options */}); });
+ testDebugDump([](const auto& handle) { return dump(device, handle); });
}
TEST_F(AudioPrimaryHidlTest, DebugDumpInvalidArguments) {
doc::test("Check that the hal dump doesn't crash on invalid arguments");
- ASSERT_OK(device->debug(hidl_handle(), {/* options */}));
+ ASSERT_OK(dump(device, hidl_handle()));
}
TEST_F(AudioPrimaryHidlTest, SetConnectedState) {
@@ -723,17 +747,16 @@
address.device = AudioDevice::OUT_DEFAULT;
const AudioConfig& config = GetParam();
// TODO: test all flag combination
- auto flags = hidl_bitfield<AudioOutputFlag>(AudioOutputFlag::NONE);
+ auto flags = mkEnumBitfield(AudioOutputFlag::NONE);
testOpen(
[&](AudioIoHandle handle, AudioConfig config, auto cb) {
- return device->openOutputStream(handle, address, config, flags, initialMetadata,
- cb);
+ return device->openOutputStream(handle, address, config, flags, initMetadata, cb);
},
config);
}
protected:
- const SourceMetadata initialMetadata = {
+ const SourceMetadata initMetadata = {
{{AudioUsage::MEDIA, AudioContentType::MUSIC, 1 /* gain */}}};
};
TEST_P(OutputStreamTest, OpenOutputStreamTest) {
@@ -764,16 +787,16 @@
address.device = AudioDevice::IN_DEFAULT;
const AudioConfig& config = GetParam();
// TODO: test all supported flags and source
- auto flags = hidl_bitfield<AudioInputFlag>(AudioInputFlag::NONE);
+ auto flags = mkEnumBitfield(AudioInputFlag::NONE);
testOpen(
[&](AudioIoHandle handle, AudioConfig config, auto cb) {
- return device->openInputStream(handle, address, config, flags, initialMetadata, cb);
+ return device->openInputStream(handle, address, config, flags, initMetadata, cb);
},
config);
}
protected:
- const SinkMetadata initialMetadata = {{{AudioSource::DEFAULT, 1 /* gain */}}};
+ const SinkMetadata initMetadata = {{{AudioSource::DEFAULT, 1 /* gain */}}};
};
TEST_P(InputStreamTest, OpenInputStreamTest) {
@@ -842,19 +865,20 @@
TEST_IO_STREAM(GetBufferSize, "Check that the stream buffer size== the one it was opened with",
ASSERT_GE(extract(stream->getBufferSize()), extract(stream->getFrameSize())));
-template <class Property, class CapablityGetter>
+template <class Property, class CapabilityGetter>
static void testCapabilityGetter(const string& name, IStream* stream,
- CapablityGetter capablityGetter,
+ CapabilityGetter capabilityGetter,
Return<Property> (IStream::*getter)(),
Return<Result> (IStream::*setter)(Property),
bool currentMustBeSupported = true) {
hidl_vec<Property> capabilities;
- auto ret = capablityGetter(stream, capabilities);
- if (ret == Result::NOT_SUPPORTED) {
+ auto ret = capabilityGetter(stream, capabilities);
+ ASSERT_RESULT(okOrNotSupported, ret);
+ bool notSupported = ret == Result::NOT_SUPPORTED;
+ if (notSupported) {
doc::partialTest(name + " is not supported");
return;
};
- ASSERT_OK(ret);
if (currentMustBeSupported) {
ASSERT_NE(0U, capabilities.size()) << name << " must not return an empty list";
@@ -878,29 +902,32 @@
}
}
-Result getSupportedSampleRates(IStream* stream, hidl_vec<uint32_t>& rates) {
- Result res;
- EXPECT_OK(stream->getSupportedSampleRates(extract(stream->getFormat()), returnIn(res, rates)));
- return res;
-}
+struct GetSupported {
+ static Result sampleRates(IStream* stream, hidl_vec<uint32_t>& rates) {
+ Result res;
+ EXPECT_OK(
+ stream->getSupportedSampleRates(extract(stream->getFormat()), returnIn(res, rates)));
+ return res;
+ }
-Result getSupportedChannelMasks(IStream* stream,
- hidl_vec<hidl_bitfield<AudioChannelMask>>& channels) {
- Result res;
- EXPECT_OK(
- stream->getSupportedChannelMasks(extract(stream->getFormat()), returnIn(res, channels)));
- return res;
-}
+ static Result channelMasks(IStream* stream,
+ hidl_vec<hidl_bitfield<AudioChannelMask>>& channels) {
+ Result res;
+ EXPECT_OK(stream->getSupportedChannelMasks(extract(stream->getFormat()),
+ returnIn(res, channels)));
+ return res;
+ }
-Result getSupportedFormats(IStream* stream, hidl_vec<AudioFormat>& capabilities) {
- EXPECT_OK(stream->getSupportedFormats(returnIn(capabilities)));
- // TODO: this should be an optional function
- return Result::OK;
-}
+ static Result formats(IStream* stream, hidl_vec<AudioFormat>& capabilities) {
+ EXPECT_OK(stream->getSupportedFormats(returnIn(capabilities)));
+ // TODO: this should be an optional function
+ return Result::OK;
+ }
+};
TEST_IO_STREAM(SupportedSampleRate, "Check that the stream sample rate is declared as supported",
testCapabilityGetter("getSupportedSampleRate", stream.get(),
- &getSupportedSampleRates, &IStream::getSampleRate,
+ &GetSupported::sampleRates, &IStream::getSampleRate,
&IStream::setSampleRate,
// getSupportedSampleRate returns the native sampling rates,
// (the sampling rates that can be played without resampling)
@@ -909,11 +936,11 @@
TEST_IO_STREAM(SupportedChannelMask, "Check that the stream channel mask is declared as supported",
testCapabilityGetter("getSupportedChannelMask", stream.get(),
- &getSupportedChannelMasks, &IStream::getChannelMask,
+ &GetSupported::channelMasks, &IStream::getChannelMask,
&IStream::setChannelMask))
TEST_IO_STREAM(SupportedFormat, "Check that the stream format is declared as supported",
- testCapabilityGetter("getSupportedFormat", stream.get(), &getSupportedFormats,
+ testCapabilityGetter("getSupportedFormat", stream.get(), &GetSupported::formats,
&IStream::getFormat, &IStream::setFormat))
static void testGetDevices(IStream* stream, AudioDevice expectedDevice) {
@@ -950,7 +977,7 @@
static void testGetAudioProperties(IStream* stream, AudioConfig expectedConfig) {
uint32_t sampleRateHz;
- hidl_bitfield<AudioChannelMask> mask;
+ auto mask = mkEnumBitfield<AudioChannelMask>({});
AudioFormat format;
stream->getAudioProperties(returnIn(sampleRateHz, mask, format));
@@ -982,10 +1009,9 @@
static void checkGetNoParameter(IStream* stream, hidl_vec<hidl_string> keys,
initializer_list<Result> expectedResults) {
- hidl_vec<ParameterValue> context;
hidl_vec<ParameterValue> parameters;
Result res;
- ASSERT_OK(stream->getParameters(context, keys, returnIn(res, parameters)));
+ ASSERT_OK(Parameters::get(stream, keys, returnIn(res, parameters)));
ASSERT_RESULT(expectedResults, res);
if (res == Result::OK) {
for (auto& parameter : parameters) {
@@ -1006,7 +1032,7 @@
{Result::NOT_SUPPORTED}))
TEST_IO_STREAM(setEmptySetParameter, "Set the values of an empty set of parameters",
- ASSERT_RESULT(Result::OK, stream->setParameters({}, {})))
+ ASSERT_RESULT(Result::OK, Parameters::set(stream, {})))
TEST_IO_STREAM(setNonExistingParameter, "Set the values of an non existing parameter",
// Unfortunately, the set_parameter legacy interface did not return any
@@ -1014,14 +1040,14 @@
// To allow implementation to just wrapped the legacy one, consider OK as a
// valid result for setting a non existing parameter.
ASSERT_RESULT(okOrNotSupportedOrInvalidArgs,
- stream->setParameters({}, {{"non existing key", "0"}})))
+ Parameters::set(stream, {{"non existing key", "0"}})))
TEST_IO_STREAM(DebugDump, "Check that a stream can dump its state without error",
- testDebugDump([this](const auto& handle) { return stream->debug(handle, {}); }))
+ testDebugDump([this](const auto& handle) { return dump(stream, handle); }))
TEST_IO_STREAM(DebugDumpInvalidArguments,
"Check that the stream dump doesn't crash on invalid arguments",
- ASSERT_OK(stream->debug(hidl_handle(), {})))
+ ASSERT_OK(dump(stream, hidl_handle())))
//////////////////////////////////////////////////////////////////////////////
////////////////////////////// addRemoveEffect ///////////////////////////////
@@ -1190,7 +1216,7 @@
ASSERT_OK(stream->updateSinkMetadata({}));
// Restore initial
- ASSERT_OK(stream->updateSinkMetadata(initialMetadata));
+ ASSERT_OK(stream->updateSinkMetadata(initMetadata));
}
//////////////////////////////////////////////////////////////////////////////
@@ -1443,7 +1469,7 @@
ASSERT_OK(stream->updateSourceMetadata({}));
// Restore initial
- ASSERT_OK(stream->updateSourceMetadata(initialMetadata));
+ ASSERT_OK(stream->updateSourceMetadata(initMetadata));
}
//////////////////////////////////////////////////////////////////////////////
diff --git a/audio/core/4.0/vts/functional/ValidateAudioConfiguration.cpp b/audio/core/4.0/vts/functional/ValidateAudioConfiguration.cpp
index a64513f..237ef47 100644
--- a/audio/core/4.0/vts/functional/ValidateAudioConfiguration.cpp
+++ b/audio/core/4.0/vts/functional/ValidateAudioConfiguration.cpp
@@ -19,12 +19,19 @@
#include "utility/ValidateXml.h"
+// Stringify the argument.
+#define QUOTE(x) #x
+#define STRINGIFY(x) QUOTE(x)
+
+#define AUDIO_HAL_VERSION V4_0
+
TEST(CheckConfig, audioPolicyConfigurationValidation) {
RecordProperty("description",
"Verify that the audio policy configuration file "
"is valid according to the schema");
std::vector<const char*> locations = {"/odm/etc", "/vendor/etc", "/system/etc"};
- EXPECT_ONE_VALID_XML_MULTIPLE_LOCATIONS("audio_policy_configuration.xml", locations,
- "/data/local/tmp/audio_policy_configuration_V4_0.xsd");
+ const char* xsd =
+ "/data/local/tmp/audio_policy_configuration_" STRINGIFY(AUDIO_HAL_VERSION) ".xsd";
+ EXPECT_ONE_VALID_XML_MULTIPLE_LOCATIONS("audio_policy_configuration.xml", locations, xsd);
}
diff --git a/audio/effect/2.0/vts/functional/Android.bp b/audio/effect/2.0/vts/functional/Android.bp
index f3fefc3..38ca315 100644
--- a/audio/effect/2.0/vts/functional/Android.bp
+++ b/audio/effect/2.0/vts/functional/Android.bp
@@ -32,5 +32,8 @@
"libicuuc_stubdata",
"libxml2",
],
+ header_libs: [
+ "android.hardware.audio.common.util@all-versions",
+ ],
test_suites: ["general-tests"],
}
diff --git a/audio/effect/2.0/vts/functional/ValidateAudioEffectsConfiguration.cpp b/audio/effect/2.0/vts/functional/ValidateAudioEffectsConfiguration.cpp
index bf080d3..040c93f 100644
--- a/audio/effect/2.0/vts/functional/ValidateAudioEffectsConfiguration.cpp
+++ b/audio/effect/2.0/vts/functional/ValidateAudioEffectsConfiguration.cpp
@@ -21,12 +21,19 @@
#include "utility/ValidateXml.h"
+// Stringify the argument.
+#define QUOTE(x) #x
+#define STRINGIFY(x) QUOTE(x)
+
+#define AUDIO_HAL_VERSION V2_0
+
TEST(CheckConfig, audioEffectsConfigurationValidation) {
RecordProperty("description",
"Verify that the effects configuration file is valid according to the schema");
using namespace android::effectsConfig;
std::vector<const char*> locations(std::begin(DEFAULT_LOCATIONS), std::end(DEFAULT_LOCATIONS));
- EXPECT_VALID_XML_MULTIPLE_LOCATIONS(DEFAULT_NAME, locations,
- "/data/local/tmp/audio_effects_conf_V2_0.xsd");
+ const char* xsd = "/data/local/tmp/audio_effects_conf_" STRINGIFY(AUDIO_HAL_VERSION) ".xsd";
+ // In V2, audio effect XML is not required. .conf is still allowed though deprecated
+ EXPECT_VALID_XML_MULTIPLE_LOCATIONS(DEFAULT_NAME, locations, xsd);
}
diff --git a/audio/effect/2.0/vts/functional/VtsHalAudioEffectTargetTest.cpp b/audio/effect/2.0/vts/functional/VtsHalAudioEffectTargetTest.cpp
index ea755ae..078e420 100644
--- a/audio/effect/2.0/vts/functional/VtsHalAudioEffectTargetTest.cpp
+++ b/audio/effect/2.0/vts/functional/VtsHalAudioEffectTargetTest.cpp
@@ -26,6 +26,8 @@
#include <android/hidl/allocator/1.0/IAllocator.h>
#include <android/hidl/memory/1.0/IMemory.h>
+#include <common/all-versions/VersionUtils.h>
+
#include <VtsHalHidlTargetTestBase.h>
#include <VtsHalHidlTargetTestEnvBase.h>
@@ -37,6 +39,7 @@
using android::hardware::MQDescriptorSync;
using android::hardware::Return;
using android::hardware::Void;
+using android::hardware::audio::common::utils::mkEnumBitfield;
using android::hardware::audio::common::V2_0::AudioDevice;
using android::hardware::audio::common::V2_0::AudioHandleConsts;
using android::hardware::audio::common::V2_0::AudioMode;
@@ -396,7 +399,7 @@
TEST_F(AudioEffectHidlTest, SetDevice) {
description("Verify that SetDevice works for an output chain effect");
- Return<Result> ret = effect->setDevice(AudioDevice::OUT_SPEAKER);
+ Return<Result> ret = effect->setDevice(mkEnumBitfield(AudioDevice::OUT_SPEAKER));
EXPECT_TRUE(ret.isOk());
EXPECT_EQ(Result::OK, ret);
}
@@ -446,7 +449,7 @@
TEST_F(AudioEffectHidlTest, SetInputDevice) {
description("Verify that SetInputDevice does not crash");
- Return<Result> ret = effect->setInputDevice(AudioDevice::IN_BUILTIN_MIC);
+ Return<Result> ret = effect->setInputDevice(mkEnumBitfield(AudioDevice::IN_BUILTIN_MIC));
EXPECT_TRUE(ret.isOk());
}
diff --git a/audio/effect/4.0/vts/functional/ValidateAudioEffectsConfiguration.cpp b/audio/effect/4.0/vts/functional/ValidateAudioEffectsConfiguration.cpp
index 6338563..2e94143 100644
--- a/audio/effect/4.0/vts/functional/ValidateAudioEffectsConfiguration.cpp
+++ b/audio/effect/4.0/vts/functional/ValidateAudioEffectsConfiguration.cpp
@@ -21,12 +21,19 @@
#include "utility/ValidateXml.h"
+// Stringify the argument.
+#define QUOTE(x) #x
+#define STRINGIFY(x) QUOTE(x)
+
+#define AUDIO_HAL_VERSION V4_0
+
TEST(CheckConfig, audioEffectsConfigurationValidation) {
RecordProperty("description",
"Verify that the effects configuration file is valid according to the schema");
using namespace android::effectsConfig;
std::vector<const char*> locations(std::begin(DEFAULT_LOCATIONS), std::end(DEFAULT_LOCATIONS));
- EXPECT_ONE_VALID_XML_MULTIPLE_LOCATIONS(DEFAULT_NAME, locations,
- "/data/local/tmp/audio_effects_conf_V4_0.xsd");
+ const char* xsd = "/data/local/tmp/audio_effects_conf_" STRINGIFY(AUDIO_HAL_VERSION) ".xsd";
+ // Starting with V4, audio effect XML is required
+ EXPECT_ONE_VALID_XML_MULTIPLE_LOCATIONS(DEFAULT_NAME, locations, xsd);
}
diff --git a/audio/effect/4.0/vts/functional/VtsHalAudioEffectTargetTest.cpp b/audio/effect/4.0/vts/functional/VtsHalAudioEffectTargetTest.cpp
index 5c10c69..96b8602 100644
--- a/audio/effect/4.0/vts/functional/VtsHalAudioEffectTargetTest.cpp
+++ b/audio/effect/4.0/vts/functional/VtsHalAudioEffectTargetTest.cpp
@@ -39,7 +39,7 @@
using android::hardware::MQDescriptorSync;
using android::hardware::Return;
using android::hardware::Void;
-using android::hardware::audio::common::utils::mkBitfield;
+using android::hardware::audio::common::utils::mkEnumBitfield;
using android::hardware::audio::common::V4_0::AudioDevice;
using android::hardware::audio::common::V4_0::AudioHandleConsts;
using android::hardware::audio::common::V4_0::AudioMode;
@@ -399,7 +399,7 @@
TEST_F(AudioEffectHidlTest, SetDevice) {
description("Verify that SetDevice works for an output chain effect");
- Return<Result> ret = effect->setDevice(mkBitfield(AudioDevice::OUT_SPEAKER));
+ Return<Result> ret = effect->setDevice(mkEnumBitfield(AudioDevice::OUT_SPEAKER));
EXPECT_TRUE(ret.isOk());
EXPECT_EQ(Result::OK, ret);
}
@@ -449,7 +449,7 @@
TEST_F(AudioEffectHidlTest, SetInputDevice) {
description("Verify that SetInputDevice does not crash");
- Return<Result> ret = effect->setInputDevice(mkBitfield(AudioDevice::IN_BUILTIN_MIC));
+ Return<Result> ret = effect->setInputDevice(mkEnumBitfield(AudioDevice::IN_BUILTIN_MIC));
EXPECT_TRUE(ret.isOk());
}
diff --git a/audio/effect/all-versions/default/include/effect/all-versions/default/Conversions.impl.h b/audio/effect/all-versions/default/include/effect/all-versions/default/Conversions.impl.h
index de67d89..0884d8f 100644
--- a/audio/effect/all-versions/default/include/effect/all-versions/default/Conversions.impl.h
+++ b/audio/effect/all-versions/default/include/effect/all-versions/default/Conversions.impl.h
@@ -22,7 +22,7 @@
#include <common/all-versions/VersionUtils.h>
using ::android::hardware::audio::common::AUDIO_HAL_VERSION::HidlUtils;
-using ::android::hardware::audio::common::utils::mkEnumConverter;
+using ::android::hardware::audio::common::utils::EnumBitfield;
namespace android {
namespace hardware {
@@ -35,7 +35,7 @@
EffectDescriptor* descriptor) {
HidlUtils::uuidFromHal(halDescriptor.type, &descriptor->type);
HidlUtils::uuidFromHal(halDescriptor.uuid, &descriptor->uuid);
- descriptor->flags = mkEnumConverter<EffectFlags>(halDescriptor.flags);
+ descriptor->flags = EnumBitfield<EffectFlags>(halDescriptor.flags);
descriptor->cpuLoad = halDescriptor.cpuLoad;
descriptor->memoryUsage = halDescriptor.memoryUsage;
memcpy(descriptor->name.data(), halDescriptor.name, descriptor->name.size());