blob: 0e15960792b33ab43e9264709a79c8c59eefa4ab [file] [log] [blame]
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <string>
#include <vector>
#include <gtest/gtest.h>
#define LOG_TAG "CoreUtils_Test"
#include <log/log.h>
#include PATH(APM_XSD_ENUMS_H_FILENAME)
#include <system/audio.h>
#include <util/CoreUtils.h>
#include <xsdc/XsdcSupport.h>
using namespace android;
using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION;
using ::android::hardware::hidl_vec;
using ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::CoreUtils;
namespace xsd {
using namespace ::android::audio::policy::configuration::CPP_VERSION;
}
static constexpr audio_channel_mask_t kInvalidHalChannelMask = AUDIO_CHANNEL_INVALID;
static constexpr audio_content_type_t kInvalidHalContentType =
static_cast<audio_content_type_t>(0xFFFFFFFFU);
static constexpr audio_devices_t kInvalidHalDevice = static_cast<audio_devices_t>(0xFFFFFFFFU);
static constexpr audio_input_flags_t kInvalidInputFlags =
static_cast<audio_input_flags_t>(0xFFFFFFFFU);
static constexpr audio_output_flags_t kInvalidOutputFlags =
static_cast<audio_output_flags_t>(0xFFFFFFFFU);
// AUDIO_SOURCE_INVALID is framework-only.
static constexpr audio_source_t kInvalidHalSource = static_cast<audio_source_t>(-1);
static constexpr audio_usage_t kInvalidHalUsage = static_cast<audio_usage_t>(0xFFFFFFFFU);
static bool isInputFlag(xsd::AudioInOutFlag flag) {
return toString(flag).find("_INPUT_FLAG_") != std::string::npos;
}
static bool isOutputFlag(xsd::AudioInOutFlag flag) {
return toString(flag).find("_OUTPUT_FLAG_") != std::string::npos;
}
TEST(CoreUtils, ConvertInvalidInputFlagMask) {
CoreUtils::AudioInputFlags invalid;
EXPECT_EQ(BAD_VALUE, CoreUtils::audioInputFlagsFromHal(kInvalidInputFlags, &invalid));
audio_input_flags_t halInvalid;
invalid.resize(1);
invalid[0] = "random string";
EXPECT_EQ(BAD_VALUE, CoreUtils::audioInputFlagsToHal(invalid, &halInvalid));
}
TEST(CoreUtils, ConvertInputFlagMask) {
CoreUtils::AudioInputFlags emptyInputFlags;
audio_input_flags_t halEmptyInputFlags;
EXPECT_EQ(NO_ERROR, CoreUtils::audioInputFlagsToHal(emptyInputFlags, &halEmptyInputFlags));
EXPECT_EQ(AUDIO_INPUT_FLAG_NONE, halEmptyInputFlags);
CoreUtils::AudioInputFlags emptyInputFlagsBack;
EXPECT_EQ(NO_ERROR,
CoreUtils::audioInputFlagsFromHal(halEmptyInputFlags, &emptyInputFlagsBack));
EXPECT_EQ(emptyInputFlags, emptyInputFlagsBack);
CoreUtils::AudioInputFlags emptyInputFlagsFromNone;
EXPECT_EQ(NO_ERROR,
CoreUtils::audioInputFlagsFromHal(AUDIO_INPUT_FLAG_NONE, &emptyInputFlagsFromNone));
EXPECT_EQ(emptyInputFlags, emptyInputFlagsFromNone);
std::vector<std::string> allEnumValues;
for (const auto enumVal : xsdc_enum_range<xsd::AudioInOutFlag>{}) {
if (isInputFlag(enumVal)) {
allEnumValues.push_back(toString(enumVal));
}
}
CoreUtils::AudioInputFlags allInputFlags;
allInputFlags.resize(allEnumValues.size());
for (size_t i = 0; i < allEnumValues.size(); ++i) {
allInputFlags[i] = allEnumValues[i];
}
audio_input_flags_t halAllInputFlags;
EXPECT_EQ(NO_ERROR, CoreUtils::audioInputFlagsToHal(allInputFlags, &halAllInputFlags));
CoreUtils::AudioInputFlags allInputFlagsBack;
EXPECT_EQ(NO_ERROR, CoreUtils::audioInputFlagsFromHal(halAllInputFlags, &allInputFlagsBack));
EXPECT_EQ(allInputFlags, allInputFlagsBack);
}
TEST(CoreUtils, ConvertInvalidOutputFlagMask) {
CoreUtils::AudioOutputFlags invalid;
EXPECT_EQ(BAD_VALUE, CoreUtils::audioOutputFlagsFromHal(kInvalidOutputFlags, &invalid));
audio_output_flags_t halInvalid;
invalid.resize(1);
invalid[0] = "random string";
EXPECT_EQ(BAD_VALUE, CoreUtils::audioOutputFlagsToHal(invalid, &halInvalid));
}
TEST(CoreUtils, ConvertOutputFlagMask) {
CoreUtils::AudioOutputFlags emptyOutputFlags;
audio_output_flags_t halEmptyOutputFlags;
EXPECT_EQ(NO_ERROR, CoreUtils::audioOutputFlagsToHal(emptyOutputFlags, &halEmptyOutputFlags));
EXPECT_EQ(AUDIO_OUTPUT_FLAG_NONE, halEmptyOutputFlags);
CoreUtils::AudioOutputFlags emptyOutputFlagsBack;
EXPECT_EQ(NO_ERROR,
CoreUtils::audioOutputFlagsFromHal(halEmptyOutputFlags, &emptyOutputFlagsBack));
EXPECT_EQ(emptyOutputFlags, emptyOutputFlagsBack);
CoreUtils::AudioOutputFlags emptyOutputFlagsFromNone;
EXPECT_EQ(NO_ERROR, CoreUtils::audioOutputFlagsFromHal(AUDIO_OUTPUT_FLAG_NONE,
&emptyOutputFlagsFromNone));
EXPECT_EQ(emptyOutputFlags, emptyOutputFlagsFromNone);
std::vector<std::string> allEnumValues;
for (const auto enumVal : xsdc_enum_range<xsd::AudioInOutFlag>{}) {
if (isOutputFlag(enumVal)) {
allEnumValues.push_back(toString(enumVal));
}
}
CoreUtils::AudioOutputFlags allOutputFlags;
allOutputFlags.resize(allEnumValues.size());
for (size_t i = 0; i < allEnumValues.size(); ++i) {
allOutputFlags[i] = allEnumValues[i];
}
audio_output_flags_t halAllOutputFlags;
EXPECT_EQ(NO_ERROR, CoreUtils::audioOutputFlagsToHal(allOutputFlags, &halAllOutputFlags));
CoreUtils::AudioOutputFlags allOutputFlagsBack;
EXPECT_EQ(NO_ERROR, CoreUtils::audioOutputFlagsFromHal(halAllOutputFlags, &allOutputFlagsBack));
EXPECT_EQ(allOutputFlags, allOutputFlagsBack);
}
static MicrophoneInfo generateValidMicrophoneInfo() {
MicrophoneInfo micInfo{};
micInfo.deviceAddress.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_IN_BUILTIN_MIC);
micInfo.channelMapping.resize(1);
micInfo.channelMapping[0] = AudioMicrophoneChannelMapping::DIRECT;
micInfo.location = AudioMicrophoneLocation::MAINBODY_MOVABLE;
micInfo.group = 42;
micInfo.indexInTheGroup = 13;
micInfo.sensitivity = 65.5;
micInfo.maxSpl = 100.5;
micInfo.minSpl = 36.6;
micInfo.directionality = AudioMicrophoneDirectionality::HYPER_CARDIOID;
micInfo.frequencyResponse.resize(1);
micInfo.frequencyResponse[0].frequency = 1000;
micInfo.frequencyResponse[0].level = 85;
micInfo.position.x = 0;
micInfo.position.y = 1;
micInfo.position.z = 0;
micInfo.orientation.x = 0;
micInfo.orientation.y = 0;
micInfo.orientation.z = 1;
return micInfo;
}
TEST(CoreUtils, ConvertInvalidMicrophoneInfo) {
MicrophoneInfo invalid;
audio_microphone_characteristic_t halInvalid{};
halInvalid.device = kInvalidHalDevice;
EXPECT_EQ(BAD_VALUE, CoreUtils::microphoneInfoFromHal(halInvalid, &invalid));
MicrophoneInfo oversizeDeviceId = generateValidMicrophoneInfo();
oversizeDeviceId.deviceId = std::string(AUDIO_MICROPHONE_ID_MAX_LEN + 1, 'A');
EXPECT_EQ(BAD_VALUE, CoreUtils::microphoneInfoToHal(oversizeDeviceId, &halInvalid));
MicrophoneInfo invalidDeviceType = generateValidMicrophoneInfo();
invalidDeviceType.deviceAddress.deviceType = "random string";
EXPECT_EQ(BAD_VALUE, CoreUtils::microphoneInfoToHal(invalidDeviceType, &halInvalid));
MicrophoneInfo oversizeChannelMapping = generateValidMicrophoneInfo();
oversizeChannelMapping.channelMapping.resize(AUDIO_CHANNEL_COUNT_MAX + 1);
EXPECT_EQ(BAD_VALUE, CoreUtils::microphoneInfoToHal(oversizeChannelMapping, &halInvalid));
MicrophoneInfo oversizeFrequencyResponses = generateValidMicrophoneInfo();
oversizeFrequencyResponses.frequencyResponse.resize(AUDIO_MICROPHONE_MAX_FREQUENCY_RESPONSES +
1);
EXPECT_EQ(BAD_VALUE, CoreUtils::microphoneInfoToHal(oversizeFrequencyResponses, &halInvalid));
}
TEST(CoreUtils, ConvertMicrophoneInfo) {
MicrophoneInfo micInfo = generateValidMicrophoneInfo();
audio_microphone_characteristic_t halMicInfo;
EXPECT_EQ(NO_ERROR, CoreUtils::microphoneInfoToHal(micInfo, &halMicInfo));
MicrophoneInfo micInfoBack;
EXPECT_EQ(NO_ERROR, CoreUtils::microphoneInfoFromHal(halMicInfo, &micInfoBack));
EXPECT_EQ(micInfo, micInfoBack);
}
static RecordTrackMetadata generateMinimalRecordTrackMetadata() {
RecordTrackMetadata metadata{};
metadata.source = toString(xsd::AudioSource::AUDIO_SOURCE_DEFAULT);
metadata.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_NONE);
return metadata;
}
static RecordTrackMetadata generateValidRecordTrackMetadata() {
RecordTrackMetadata metadata = generateMinimalRecordTrackMetadata();
metadata.tags.resize(1);
metadata.tags[0] = "VX_GOOGLE_42";
metadata.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_IN_MONO);
metadata.gain = 1.0;
return metadata;
}
static RecordTrackMetadata generateValidRecordTrackMetadataWithDevice() {
RecordTrackMetadata metadata = generateValidRecordTrackMetadata();
metadata.destination.device({});
metadata.destination.device().deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_OUT_SPEAKER);
return metadata;
}
using SinkTracks = hidl_vec<RecordTrackMetadata>;
TEST(CoreUtils, ConvertInvalidSinkMetadata) {
SinkMetadata invalidSource;
invalidSource.tracks = SinkTracks{generateMinimalRecordTrackMetadata()};
invalidSource.tracks[0].source = "random string";
EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataToHal(invalidSource, nullptr));
EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataToHalV7(invalidSource,
false /*ignoreNonVendorTags*/, nullptr));
EXPECT_EQ(BAD_VALUE,
CoreUtils::sinkMetadataToHalV7(invalidSource, true /*ignoreNonVendorTags*/, nullptr));
SinkMetadata invalidDeviceType;
invalidDeviceType.tracks = SinkTracks{generateValidRecordTrackMetadataWithDevice()};
invalidDeviceType.tracks[0].destination.device().deviceType = "random string";
EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataToHal(invalidDeviceType, nullptr));
EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataToHalV7(invalidDeviceType,
false /*ignoreNonVendorTags*/, nullptr));
EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataToHalV7(invalidDeviceType,
true /*ignoreNonVendorTags*/, nullptr));
SinkMetadata invalidChannelMask;
invalidChannelMask.tracks = SinkTracks{generateValidRecordTrackMetadata()};
invalidChannelMask.tracks[0].channelMask = "random string";
// Channel mask is sliced away by 'sinkMetadataToHal'
EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataToHal(invalidChannelMask, nullptr));
EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataToHalV7(invalidChannelMask,
false /*ignoreNonVendorTags*/, nullptr));
EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataToHalV7(invalidChannelMask,
true /*ignoreNonVendorTags*/, nullptr));
SinkMetadata invalidTags;
invalidTags.tracks = SinkTracks{generateValidRecordTrackMetadata()};
invalidTags.tracks[0].tags[0] = "random string";
// Tags are sliced away by 'sinkMetadataToHal'
EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataToHal(invalidTags, nullptr));
EXPECT_EQ(BAD_VALUE,
CoreUtils::sinkMetadataToHalV7(invalidTags, false /*ignoreNonVendorTags*/, nullptr));
// Non-vendor tags should be filtered out.
EXPECT_EQ(NO_ERROR,
CoreUtils::sinkMetadataToHalV7(invalidTags, true /*ignoreNonVendorTags*/, nullptr));
// Verify that a default-initialized metadata is valid.
std::vector<record_track_metadata_t> halValid(1, record_track_metadata_t{});
std::vector<record_track_metadata_v7_t> halValidV7(1, record_track_metadata_v7_t{});
SinkMetadata valid;
EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataFromHal(halValid, &valid));
EXPECT_EQ(NO_ERROR,
CoreUtils::sinkMetadataFromHalV7(halValidV7, false /*ignoreNonVendorTags*/, &valid));
EXPECT_EQ(NO_ERROR,
CoreUtils::sinkMetadataFromHalV7(halValidV7, true /*ignoreNonVendorTags*/, &valid));
std::vector<record_track_metadata_t> halInvalidSource = {{.source = kInvalidHalSource}};
std::vector<record_track_metadata_v7_t> halInvalidSourceV7 = {
{.base = {.source = kInvalidHalSource}}};
EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataFromHal(halInvalidSource, &invalidSource));
EXPECT_EQ(BAD_VALUE,
CoreUtils::sinkMetadataFromHalV7(halInvalidSourceV7, false /*ignoreNonVendorTags*/,
&invalidSource));
EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataFromHalV7(
halInvalidSourceV7, true /*ignoreNonVendorTags*/, &invalidSource));
std::vector<record_track_metadata_t> halInvalidDeviceType = {
{.dest_device = kInvalidHalDevice}};
std::vector<record_track_metadata_v7_t> halInvalidDeviceTypeV7 = {
{.base = {.dest_device = kInvalidHalDevice}}};
EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataFromHal(halInvalidDeviceType, &invalidDeviceType));
EXPECT_EQ(BAD_VALUE,
CoreUtils::sinkMetadataFromHalV7(halInvalidDeviceTypeV7,
false /*ignoreNonVendorTags*/, &invalidDeviceType));
EXPECT_EQ(BAD_VALUE,
CoreUtils::sinkMetadataFromHalV7(halInvalidDeviceTypeV7, true /*ignoreNonVendorTags*/,
&invalidDeviceType));
std::vector<record_track_metadata_v7_t> halInvalidChannelMaskV7 = {
{.channel_mask = kInvalidHalChannelMask}};
EXPECT_EQ(BAD_VALUE,
CoreUtils::sinkMetadataFromHalV7(halInvalidChannelMaskV7,
false /*ignoreNonVendorTags*/, &invalidChannelMask));
EXPECT_EQ(BAD_VALUE,
CoreUtils::sinkMetadataFromHalV7(halInvalidChannelMaskV7,
true /*ignoreNonVendorTags*/, &invalidChannelMask));
std::vector<record_track_metadata_v7_t> halInvalidTagsV7 = {{.tags = "random string"}};
EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataFromHalV7(
halInvalidTagsV7, false /*ignoreNonVendorTags*/, &invalidTags));
// Non-vendor tags should be filtered out.
EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataFromHalV7(
halInvalidTagsV7, true /*ignoreNonVendorTags*/, &invalidTags));
}
TEST(CoreUtils, ConvertEmptySinkMetadata) {
SinkMetadata emptySinkMetadata;
std::vector<record_track_metadata_t> halEmptySinkMetadata;
EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataToHal(emptySinkMetadata, &halEmptySinkMetadata));
EXPECT_TRUE(halEmptySinkMetadata.empty());
SinkMetadata emptySinkMetadataBack;
EXPECT_EQ(NO_ERROR,
CoreUtils::sinkMetadataFromHal(halEmptySinkMetadata, &emptySinkMetadataBack));
EXPECT_EQ(emptySinkMetadata, emptySinkMetadataBack);
std::vector<record_track_metadata_v7_t> halEmptySinkMetadataV7;
EXPECT_EQ(NO_ERROR,
CoreUtils::sinkMetadataToHalV7(emptySinkMetadata, false /*ignoreNonVendorTags*/,
&halEmptySinkMetadataV7));
EXPECT_TRUE(halEmptySinkMetadataV7.empty());
SinkMetadata emptySinkMetadataBackFromV7;
EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataFromHalV7(halEmptySinkMetadataV7,
false /*ignoreNonVendorTags*/,
&emptySinkMetadataBackFromV7));
EXPECT_EQ(emptySinkMetadata, emptySinkMetadataBackFromV7);
}
class SinkMetadataConvertTest : public ::testing::TestWithParam<SinkTracks> {};
TEST_P(SinkMetadataConvertTest, ToFromHal) {
SinkMetadata sinkMetadata;
sinkMetadata.tracks = GetParam();
std::vector<record_track_metadata_t> halSinkMetadata;
EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataToHal(sinkMetadata, &halSinkMetadata));
EXPECT_EQ(sinkMetadata.tracks.size(), halSinkMetadata.size());
SinkMetadata sinkMetadataBackTrimmed;
EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataFromHal(halSinkMetadata, &sinkMetadataBackTrimmed));
// Can't compare 'sinkMetadata' to 'sinkMetadataBackTrimmed'
std::vector<record_track_metadata_v7_t> halSinkMetadataV7;
EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataToHalV7(sinkMetadata, false /*ignoreNonVendorTags*/,
&halSinkMetadataV7));
EXPECT_EQ(sinkMetadata.tracks.size(), halSinkMetadataV7.size());
SinkMetadata sinkMetadataBackFromV7;
EXPECT_EQ(NO_ERROR,
CoreUtils::sinkMetadataFromHalV7(halSinkMetadataV7, false /*ignoreNonVendorTags*/,
&sinkMetadataBackFromV7));
EXPECT_EQ(sinkMetadata, sinkMetadataBackFromV7);
std::vector<record_track_metadata_v7_t> halSinkMetadataV7FromTrimmed;
EXPECT_EQ(NO_ERROR,
CoreUtils::sinkMetadataToHalV7(sinkMetadataBackTrimmed, false /*ignoreNonVendorTags*/,
&halSinkMetadataV7FromTrimmed));
EXPECT_EQ(sinkMetadata.tracks.size(), halSinkMetadataV7FromTrimmed.size());
SinkMetadata sinkMetadataBackFromV7Trimmed;
EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataFromHalV7(halSinkMetadataV7FromTrimmed,
false /*ignoreNonVendorTags*/,
&sinkMetadataBackFromV7Trimmed));
EXPECT_EQ(sinkMetadataBackTrimmed, sinkMetadataBackFromV7Trimmed);
}
INSTANTIATE_TEST_SUITE_P(ValidRecordTrackMetadatas, SinkMetadataConvertTest,
::testing::Values(SinkTracks{generateMinimalRecordTrackMetadata()},
SinkTracks{generateValidRecordTrackMetadata()},
SinkTracks{generateValidRecordTrackMetadataWithDevice()},
SinkTracks{
generateMinimalRecordTrackMetadata(),
generateValidRecordTrackMetadata(),
generateValidRecordTrackMetadataWithDevice()}));
static PlaybackTrackMetadata generateMinimalPlaybackTrackMetadata() {
PlaybackTrackMetadata metadata{};
metadata.usage = toString(xsd::AudioUsage::AUDIO_USAGE_UNKNOWN);
metadata.contentType = toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_UNKNOWN);
metadata.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_NONE);
return metadata;
}
static PlaybackTrackMetadata generateValidPlaybackTrackMetadata() {
PlaybackTrackMetadata metadata = generateMinimalPlaybackTrackMetadata();
metadata.tags.resize(1);
metadata.tags[0] = "VX_GOOGLE_42";
metadata.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_MONO);
metadata.gain = 1.0;
return metadata;
}
using SourceTracks = hidl_vec<PlaybackTrackMetadata>;
TEST(CoreUtils, ConvertInvalidSourceMetadata) {
SourceMetadata invalidUsage;
invalidUsage.tracks = SourceTracks{generateMinimalPlaybackTrackMetadata()};
invalidUsage.tracks[0].usage = "random string";
EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataToHal(invalidUsage, nullptr));
EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataToHalV7(invalidUsage,
false /*ignoreNonVendorTags*/, nullptr));
SourceMetadata invalidContentType;
invalidContentType.tracks = SourceTracks{generateMinimalPlaybackTrackMetadata()};
invalidContentType.tracks[0].contentType = "random string";
EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataToHal(invalidContentType, nullptr));
EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataToHalV7(invalidContentType,
false /*ignoreNonVendorTags*/, nullptr));
EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataToHalV7(invalidContentType,
true /*ignoreNonVendorTags*/, nullptr));
SourceMetadata invalidChannelMask;
invalidChannelMask.tracks = SourceTracks{generateValidPlaybackTrackMetadata()};
invalidChannelMask.tracks[0].channelMask = "random string";
// Channel mask is sliced away by 'sourceMetadataToHal'
EXPECT_EQ(NO_ERROR, CoreUtils::sourceMetadataToHal(invalidChannelMask, nullptr));
EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataToHalV7(invalidChannelMask,
false /*ignoreNonVendorTags*/, nullptr));
EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataToHalV7(invalidChannelMask,
true /*ignoreNonVendorTags*/, nullptr));
SourceMetadata invalidTags;
invalidTags.tracks = SourceTracks{generateValidPlaybackTrackMetadata()};
invalidTags.tracks[0].tags[0] = "random string";
// Tags are sliced away by 'sourceMetadataToHal'
EXPECT_EQ(NO_ERROR, CoreUtils::sourceMetadataToHal(invalidTags, nullptr));
EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataToHalV7(invalidTags,
false /*ignoreNonVendorTags*/, nullptr));
// Non-vendor tags should be filtered out.
EXPECT_EQ(NO_ERROR,
CoreUtils::sourceMetadataToHalV7(invalidTags, true /*ignoreNonVendorTags*/, nullptr));
// Verify that a default-initialized metadata is valid.
std::vector<playback_track_metadata_t> halValid(1, playback_track_metadata_t{});
std::vector<playback_track_metadata_v7_t> halValidV7(1, playback_track_metadata_v7_t{});
SourceMetadata valid;
EXPECT_EQ(NO_ERROR, CoreUtils::sourceMetadataFromHal(halValid, &valid));
EXPECT_EQ(NO_ERROR, CoreUtils::sourceMetadataFromHalV7(halValidV7,
false /*ignoreNonVendorTags*/, &valid));
EXPECT_EQ(NO_ERROR,
CoreUtils::sourceMetadataFromHalV7(halValidV7, true /*ignoreNonVendorTags*/, &valid));
std::vector<playback_track_metadata_t> halInvalidUsage = {{.usage = kInvalidHalUsage}};
std::vector<playback_track_metadata_v7_t> halInvalidUsageV7 = {
{.base = {.usage = kInvalidHalUsage}}};
EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataFromHal(halInvalidUsage, &invalidUsage));
EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataFromHalV7(
halInvalidUsageV7, false /*ignoreNonVendorTags*/, &invalidUsage));
EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataFromHalV7(
halInvalidUsageV7, true /*ignoreNonVendorTags*/, &invalidUsage));
std::vector<playback_track_metadata_t> halInvalidContentType = {
{.content_type = kInvalidHalContentType}};
std::vector<playback_track_metadata_v7_t> halInvalidContentTypeV7 = {
{.base = {.content_type = kInvalidHalContentType}}};
EXPECT_EQ(BAD_VALUE,
CoreUtils::sourceMetadataFromHal(halInvalidContentType, &invalidContentType));
EXPECT_EQ(BAD_VALUE,
CoreUtils::sourceMetadataFromHalV7(
halInvalidContentTypeV7, false /*ignoreNonVendorTags*/, &invalidContentType));
EXPECT_EQ(BAD_VALUE,
CoreUtils::sourceMetadataFromHalV7(
halInvalidContentTypeV7, true /*ignoreNonVendorTags*/, &invalidContentType));
std::vector<playback_track_metadata_v7_t> halInvalidChannelMaskV7 = {
{.channel_mask = kInvalidHalChannelMask}};
EXPECT_EQ(BAD_VALUE,
CoreUtils::sourceMetadataFromHalV7(
halInvalidChannelMaskV7, false /*ignoreNonVendorTags*/, &invalidChannelMask));
EXPECT_EQ(BAD_VALUE,
CoreUtils::sourceMetadataFromHalV7(
halInvalidChannelMaskV7, true /*ignoreNonVendorTags*/, &invalidChannelMask));
std::vector<playback_track_metadata_v7_t> halInvalidTagsV7 = {{.tags = "random string"}};
EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataFromHalV7(
halInvalidTagsV7, false /*ignoreNonVendorTags*/, &invalidTags));
// Non-vendor tags should be filtered out.
EXPECT_EQ(NO_ERROR, CoreUtils::sourceMetadataFromHalV7(
halInvalidTagsV7, true /*ignoreNonVendorTags*/, &invalidTags));
}
TEST(CoreUtils, ConvertEmptySourceMetadata) {
SourceMetadata emptySourceMetadata;
std::vector<playback_track_metadata_t> halEmptySourceMetadata;
EXPECT_EQ(NO_ERROR,
CoreUtils::sourceMetadataToHal(emptySourceMetadata, &halEmptySourceMetadata));
EXPECT_TRUE(halEmptySourceMetadata.empty());
SourceMetadata emptySourceMetadataBack;
EXPECT_EQ(NO_ERROR,
CoreUtils::sourceMetadataFromHal(halEmptySourceMetadata, &emptySourceMetadataBack));
EXPECT_EQ(emptySourceMetadata, emptySourceMetadataBack);
std::vector<playback_track_metadata_v7_t> halEmptySourceMetadataV7;
EXPECT_EQ(NO_ERROR,
CoreUtils::sourceMetadataToHalV7(emptySourceMetadata, false /*ignoreNonVendorTags*/,
&halEmptySourceMetadataV7));
EXPECT_TRUE(halEmptySourceMetadataV7.empty());
SourceMetadata emptySourceMetadataBackFromV7;
EXPECT_EQ(NO_ERROR, CoreUtils::sourceMetadataFromHalV7(halEmptySourceMetadataV7,
false /*ignoreNonVendorTags*/,
&emptySourceMetadataBackFromV7));
EXPECT_EQ(emptySourceMetadata, emptySourceMetadataBackFromV7);
}
class SourceMetadataConvertTest : public ::testing::TestWithParam<SourceTracks> {};
TEST_P(SourceMetadataConvertTest, ToFromHal) {
SourceMetadata sourceMetadata;
sourceMetadata.tracks = GetParam();
std::vector<playback_track_metadata_t> halSourceMetadata;
EXPECT_EQ(NO_ERROR, CoreUtils::sourceMetadataToHal(sourceMetadata, &halSourceMetadata));
EXPECT_EQ(sourceMetadata.tracks.size(), halSourceMetadata.size());
SourceMetadata sourceMetadataBackTrimmed;
EXPECT_EQ(NO_ERROR,
CoreUtils::sourceMetadataFromHal(halSourceMetadata, &sourceMetadataBackTrimmed));
// Can't compare 'sourceMetadata' to 'sourceMetadataBackTrimmed'
std::vector<playback_track_metadata_v7_t> halSourceMetadataV7;
EXPECT_EQ(NO_ERROR,
CoreUtils::sourceMetadataToHalV7(sourceMetadata, false /*ignoreNonVendorTags*/,
&halSourceMetadataV7));
EXPECT_EQ(sourceMetadata.tracks.size(), halSourceMetadataV7.size());
SourceMetadata sourceMetadataBackFromV7;
EXPECT_EQ(NO_ERROR,
CoreUtils::sourceMetadataFromHalV7(halSourceMetadataV7, false /*ignoreNonVendorTags*/,
&sourceMetadataBackFromV7));
EXPECT_EQ(sourceMetadata, sourceMetadataBackFromV7);
std::vector<playback_track_metadata_v7_t> halSourceMetadataV7FromTrimmed;
EXPECT_EQ(NO_ERROR, CoreUtils::sourceMetadataToHalV7(sourceMetadataBackTrimmed,
false /*ignoreNonVendorTags*/,
&halSourceMetadataV7FromTrimmed));
EXPECT_EQ(sourceMetadata.tracks.size(), halSourceMetadataV7FromTrimmed.size());
SourceMetadata sourceMetadataBackFromV7Trimmed;
EXPECT_EQ(NO_ERROR, CoreUtils::sourceMetadataFromHalV7(halSourceMetadataV7FromTrimmed,
false /*ignoreNonVendorTags*/,
&sourceMetadataBackFromV7Trimmed));
EXPECT_EQ(sourceMetadataBackTrimmed, sourceMetadataBackFromV7Trimmed);
}
INSTANTIATE_TEST_SUITE_P(ValidPlaybackTrackMetadatas, SourceMetadataConvertTest,
::testing::Values(SourceTracks{generateMinimalPlaybackTrackMetadata()},
SourceTracks{generateValidPlaybackTrackMetadata()},
SourceTracks{generateMinimalPlaybackTrackMetadata(),
generateValidPlaybackTrackMetadata()}));