1 /*
2 * Copyright (C) 2021 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <string>
18 #include <vector>
19
20 #include <gtest/gtest.h>
21
22 #define LOG_TAG "CoreUtils_Test"
23 #include <log/log.h>
24
25 #include <android_audio_policy_configuration_V7_0-enums.h>
26 #include <system/audio.h>
27 #include <util/CoreUtils.h>
28 #include <xsdc/XsdcSupport.h>
29
30 using namespace android;
31 using namespace ::android::hardware::audio::common::CPP_VERSION;
32 using namespace ::android::hardware::audio::CPP_VERSION;
33 using ::android::hardware::hidl_vec;
34 using ::android::hardware::audio::CPP_VERSION::implementation::CoreUtils;
35 namespace xsd {
36 using namespace ::android::audio::policy::configuration::V7_0;
37 }
38
39 static constexpr audio_channel_mask_t kInvalidHalChannelMask = AUDIO_CHANNEL_INVALID;
40 static constexpr audio_content_type_t kInvalidHalContentType =
41 static_cast<audio_content_type_t>(0xFFFFFFFFU);
42 static constexpr audio_devices_t kInvalidHalDevice = static_cast<audio_devices_t>(0xFFFFFFFFU);
43 static constexpr audio_input_flags_t kInvalidInputFlags =
44 static_cast<audio_input_flags_t>(0xFFFFFFFFU);
45 static constexpr audio_output_flags_t kInvalidOutputFlags =
46 static_cast<audio_output_flags_t>(0xFFFFFFFFU);
47 // AUDIO_SOURCE_INVALID is framework-only.
48 static constexpr audio_source_t kInvalidHalSource = static_cast<audio_source_t>(-1);
49 static constexpr audio_usage_t kInvalidHalUsage = static_cast<audio_usage_t>(0xFFFFFFFFU);
50
isInputFlag(xsd::AudioInOutFlag flag)51 static bool isInputFlag(xsd::AudioInOutFlag flag) {
52 return toString(flag).find("_INPUT_FLAG_") != std::string::npos;
53 }
54
isOutputFlag(xsd::AudioInOutFlag flag)55 static bool isOutputFlag(xsd::AudioInOutFlag flag) {
56 return toString(flag).find("_OUTPUT_FLAG_") != std::string::npos;
57 }
58
TEST(CoreUtils,ConvertInvalidInputFlagMask)59 TEST(CoreUtils, ConvertInvalidInputFlagMask) {
60 CoreUtils::AudioInputFlags invalid;
61 EXPECT_EQ(BAD_VALUE, CoreUtils::audioInputFlagsFromHal(kInvalidInputFlags, &invalid));
62 audio_input_flags_t halInvalid;
63 invalid.resize(1);
64 invalid[0] = "random string";
65 EXPECT_EQ(BAD_VALUE, CoreUtils::audioInputFlagsToHal(invalid, &halInvalid));
66 }
67
TEST(CoreUtils,ConvertInputFlagMask)68 TEST(CoreUtils, ConvertInputFlagMask) {
69 CoreUtils::AudioInputFlags emptyInputFlags;
70 audio_input_flags_t halEmptyInputFlags;
71 EXPECT_EQ(NO_ERROR, CoreUtils::audioInputFlagsToHal(emptyInputFlags, &halEmptyInputFlags));
72 EXPECT_EQ(AUDIO_INPUT_FLAG_NONE, halEmptyInputFlags);
73 CoreUtils::AudioInputFlags emptyInputFlagsBack;
74 EXPECT_EQ(NO_ERROR,
75 CoreUtils::audioInputFlagsFromHal(halEmptyInputFlags, &emptyInputFlagsBack));
76 EXPECT_EQ(emptyInputFlags, emptyInputFlagsBack);
77 CoreUtils::AudioInputFlags emptyInputFlagsFromNone;
78 EXPECT_EQ(NO_ERROR,
79 CoreUtils::audioInputFlagsFromHal(AUDIO_INPUT_FLAG_NONE, &emptyInputFlagsFromNone));
80 EXPECT_EQ(emptyInputFlags, emptyInputFlagsFromNone);
81
82 std::vector<std::string> allEnumValues;
83 for (const auto enumVal : xsdc_enum_range<xsd::AudioInOutFlag>{}) {
84 if (isInputFlag(enumVal)) {
85 allEnumValues.push_back(toString(enumVal));
86 }
87 }
88 CoreUtils::AudioInputFlags allInputFlags;
89 allInputFlags.resize(allEnumValues.size());
90 for (size_t i = 0; i < allEnumValues.size(); ++i) {
91 allInputFlags[i] = allEnumValues[i];
92 }
93 audio_input_flags_t halAllInputFlags;
94 EXPECT_EQ(NO_ERROR, CoreUtils::audioInputFlagsToHal(allInputFlags, &halAllInputFlags));
95 CoreUtils::AudioInputFlags allInputFlagsBack;
96 EXPECT_EQ(NO_ERROR, CoreUtils::audioInputFlagsFromHal(halAllInputFlags, &allInputFlagsBack));
97 EXPECT_EQ(allInputFlags, allInputFlagsBack);
98 }
99
TEST(CoreUtils,ConvertInvalidOutputFlagMask)100 TEST(CoreUtils, ConvertInvalidOutputFlagMask) {
101 CoreUtils::AudioOutputFlags invalid;
102 EXPECT_EQ(BAD_VALUE, CoreUtils::audioOutputFlagsFromHal(kInvalidOutputFlags, &invalid));
103 audio_output_flags_t halInvalid;
104 invalid.resize(1);
105 invalid[0] = "random string";
106 EXPECT_EQ(BAD_VALUE, CoreUtils::audioOutputFlagsToHal(invalid, &halInvalid));
107 }
108
TEST(CoreUtils,ConvertOutputFlagMask)109 TEST(CoreUtils, ConvertOutputFlagMask) {
110 CoreUtils::AudioOutputFlags emptyOutputFlags;
111 audio_output_flags_t halEmptyOutputFlags;
112 EXPECT_EQ(NO_ERROR, CoreUtils::audioOutputFlagsToHal(emptyOutputFlags, &halEmptyOutputFlags));
113 EXPECT_EQ(AUDIO_OUTPUT_FLAG_NONE, halEmptyOutputFlags);
114 CoreUtils::AudioOutputFlags emptyOutputFlagsBack;
115 EXPECT_EQ(NO_ERROR,
116 CoreUtils::audioOutputFlagsFromHal(halEmptyOutputFlags, &emptyOutputFlagsBack));
117 EXPECT_EQ(emptyOutputFlags, emptyOutputFlagsBack);
118 CoreUtils::AudioOutputFlags emptyOutputFlagsFromNone;
119 EXPECT_EQ(NO_ERROR, CoreUtils::audioOutputFlagsFromHal(AUDIO_OUTPUT_FLAG_NONE,
120 &emptyOutputFlagsFromNone));
121 EXPECT_EQ(emptyOutputFlags, emptyOutputFlagsFromNone);
122
123 std::vector<std::string> allEnumValues;
124 for (const auto enumVal : xsdc_enum_range<xsd::AudioInOutFlag>{}) {
125 if (isOutputFlag(enumVal)) {
126 allEnumValues.push_back(toString(enumVal));
127 }
128 }
129 CoreUtils::AudioOutputFlags allOutputFlags;
130 allOutputFlags.resize(allEnumValues.size());
131 for (size_t i = 0; i < allEnumValues.size(); ++i) {
132 allOutputFlags[i] = allEnumValues[i];
133 }
134 audio_output_flags_t halAllOutputFlags;
135 EXPECT_EQ(NO_ERROR, CoreUtils::audioOutputFlagsToHal(allOutputFlags, &halAllOutputFlags));
136 CoreUtils::AudioOutputFlags allOutputFlagsBack;
137 EXPECT_EQ(NO_ERROR, CoreUtils::audioOutputFlagsFromHal(halAllOutputFlags, &allOutputFlagsBack));
138 EXPECT_EQ(allOutputFlags, allOutputFlagsBack);
139 }
140
generateValidMicrophoneInfo()141 static MicrophoneInfo generateValidMicrophoneInfo() {
142 MicrophoneInfo micInfo{};
143 micInfo.deviceAddress.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_IN_BUILTIN_MIC);
144 micInfo.channelMapping.resize(1);
145 micInfo.channelMapping[0] = AudioMicrophoneChannelMapping::DIRECT;
146 micInfo.location = AudioMicrophoneLocation::MAINBODY_MOVABLE;
147 micInfo.group = 42;
148 micInfo.indexInTheGroup = 13;
149 micInfo.sensitivity = 65.5;
150 micInfo.maxSpl = 100.5;
151 micInfo.minSpl = 36.6;
152 micInfo.directionality = AudioMicrophoneDirectionality::HYPER_CARDIOID;
153 micInfo.frequencyResponse.resize(1);
154 micInfo.frequencyResponse[0].frequency = 1000;
155 micInfo.frequencyResponse[0].level = 85;
156 micInfo.position.x = 0;
157 micInfo.position.y = 1;
158 micInfo.position.z = 0;
159 micInfo.orientation.x = 0;
160 micInfo.orientation.y = 0;
161 micInfo.orientation.z = 1;
162 return micInfo;
163 }
164
TEST(CoreUtils,ConvertInvalidMicrophoneInfo)165 TEST(CoreUtils, ConvertInvalidMicrophoneInfo) {
166 MicrophoneInfo invalid;
167 audio_microphone_characteristic_t halInvalid{};
168 halInvalid.device = kInvalidHalDevice;
169 EXPECT_EQ(BAD_VALUE, CoreUtils::microphoneInfoFromHal(halInvalid, &invalid));
170
171 MicrophoneInfo oversizeDeviceId = generateValidMicrophoneInfo();
172 oversizeDeviceId.deviceId = std::string(AUDIO_MICROPHONE_ID_MAX_LEN + 1, 'A');
173 EXPECT_EQ(BAD_VALUE, CoreUtils::microphoneInfoToHal(oversizeDeviceId, &halInvalid));
174 MicrophoneInfo invalidDeviceType = generateValidMicrophoneInfo();
175 invalidDeviceType.deviceAddress.deviceType = "random string";
176 EXPECT_EQ(BAD_VALUE, CoreUtils::microphoneInfoToHal(invalidDeviceType, &halInvalid));
177 MicrophoneInfo oversizeChannelMapping = generateValidMicrophoneInfo();
178 oversizeChannelMapping.channelMapping.resize(AUDIO_CHANNEL_COUNT_MAX + 1);
179 EXPECT_EQ(BAD_VALUE, CoreUtils::microphoneInfoToHal(oversizeChannelMapping, &halInvalid));
180 MicrophoneInfo oversizeFrequencyResponses = generateValidMicrophoneInfo();
181 oversizeFrequencyResponses.frequencyResponse.resize(AUDIO_MICROPHONE_MAX_FREQUENCY_RESPONSES +
182 1);
183 EXPECT_EQ(BAD_VALUE, CoreUtils::microphoneInfoToHal(oversizeFrequencyResponses, &halInvalid));
184 }
185
TEST(CoreUtils,ConvertMicrophoneInfo)186 TEST(CoreUtils, ConvertMicrophoneInfo) {
187 MicrophoneInfo micInfo = generateValidMicrophoneInfo();
188 audio_microphone_characteristic_t halMicInfo;
189 EXPECT_EQ(NO_ERROR, CoreUtils::microphoneInfoToHal(micInfo, &halMicInfo));
190 MicrophoneInfo micInfoBack;
191 EXPECT_EQ(NO_ERROR, CoreUtils::microphoneInfoFromHal(halMicInfo, &micInfoBack));
192 EXPECT_EQ(micInfo, micInfoBack);
193 }
194
generateMinimalRecordTrackMetadata()195 static RecordTrackMetadata generateMinimalRecordTrackMetadata() {
196 RecordTrackMetadata metadata{};
197 metadata.source = toString(xsd::AudioSource::AUDIO_SOURCE_DEFAULT);
198 metadata.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_NONE);
199 return metadata;
200 }
201
generateValidRecordTrackMetadata()202 static RecordTrackMetadata generateValidRecordTrackMetadata() {
203 RecordTrackMetadata metadata = generateMinimalRecordTrackMetadata();
204 metadata.tags.resize(1);
205 metadata.tags[0] = "VX_GOOGLE_42";
206 metadata.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_IN_MONO);
207 metadata.gain = 1.0;
208 return metadata;
209 }
210
generateValidRecordTrackMetadataWithDevice()211 static RecordTrackMetadata generateValidRecordTrackMetadataWithDevice() {
212 RecordTrackMetadata metadata = generateValidRecordTrackMetadata();
213 metadata.destination.device({});
214 metadata.destination.device().deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_OUT_SPEAKER);
215 return metadata;
216 }
217
218 using SinkTracks = hidl_vec<RecordTrackMetadata>;
219
TEST(CoreUtils,ConvertInvalidSinkMetadata)220 TEST(CoreUtils, ConvertInvalidSinkMetadata) {
221 SinkMetadata invalidSource;
222 invalidSource.tracks = SinkTracks{generateMinimalRecordTrackMetadata()};
223 invalidSource.tracks[0].source = "random string";
224 EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataToHal(invalidSource, nullptr));
225 EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataToHalV7(invalidSource,
226 false /*ignoreNonVendorTags*/, nullptr));
227 EXPECT_EQ(BAD_VALUE,
228 CoreUtils::sinkMetadataToHalV7(invalidSource, true /*ignoreNonVendorTags*/, nullptr));
229 SinkMetadata invalidDeviceType;
230 invalidDeviceType.tracks = SinkTracks{generateValidRecordTrackMetadataWithDevice()};
231 invalidDeviceType.tracks[0].destination.device().deviceType = "random string";
232 EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataToHal(invalidDeviceType, nullptr));
233 EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataToHalV7(invalidDeviceType,
234 false /*ignoreNonVendorTags*/, nullptr));
235 EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataToHalV7(invalidDeviceType,
236 true /*ignoreNonVendorTags*/, nullptr));
237 SinkMetadata invalidChannelMask;
238 invalidChannelMask.tracks = SinkTracks{generateValidRecordTrackMetadata()};
239 invalidChannelMask.tracks[0].channelMask = "random string";
240 // Channel mask is sliced away by 'sinkMetadataToHal'
241 EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataToHal(invalidChannelMask, nullptr));
242 EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataToHalV7(invalidChannelMask,
243 false /*ignoreNonVendorTags*/, nullptr));
244 EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataToHalV7(invalidChannelMask,
245 true /*ignoreNonVendorTags*/, nullptr));
246 SinkMetadata invalidTags;
247 invalidTags.tracks = SinkTracks{generateValidRecordTrackMetadata()};
248 invalidTags.tracks[0].tags[0] = "random string";
249 // Tags are sliced away by 'sinkMetadataToHal'
250 EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataToHal(invalidTags, nullptr));
251 EXPECT_EQ(BAD_VALUE,
252 CoreUtils::sinkMetadataToHalV7(invalidTags, false /*ignoreNonVendorTags*/, nullptr));
253 // Non-vendor tags should be filtered out.
254 EXPECT_EQ(NO_ERROR,
255 CoreUtils::sinkMetadataToHalV7(invalidTags, true /*ignoreNonVendorTags*/, nullptr));
256
257 // Verify that a default-initialized metadata is valid.
258 std::vector<record_track_metadata_t> halValid(1, record_track_metadata_t{});
259 std::vector<record_track_metadata_v7_t> halValidV7(1, record_track_metadata_v7_t{});
260 SinkMetadata valid;
261 EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataFromHal(halValid, &valid));
262 EXPECT_EQ(NO_ERROR,
263 CoreUtils::sinkMetadataFromHalV7(halValidV7, false /*ignoreNonVendorTags*/, &valid));
264 EXPECT_EQ(NO_ERROR,
265 CoreUtils::sinkMetadataFromHalV7(halValidV7, true /*ignoreNonVendorTags*/, &valid));
266
267 std::vector<record_track_metadata_t> halInvalidSource = {{.source = kInvalidHalSource}};
268 std::vector<record_track_metadata_v7_t> halInvalidSourceV7 = {
269 {.base = {.source = kInvalidHalSource}}};
270 EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataFromHal(halInvalidSource, &invalidSource));
271 EXPECT_EQ(BAD_VALUE,
272 CoreUtils::sinkMetadataFromHalV7(halInvalidSourceV7, false /*ignoreNonVendorTags*/,
273 &invalidSource));
274 EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataFromHalV7(
275 halInvalidSourceV7, true /*ignoreNonVendorTags*/, &invalidSource));
276 std::vector<record_track_metadata_t> halInvalidDeviceType = {
277 {.dest_device = kInvalidHalDevice}};
278 std::vector<record_track_metadata_v7_t> halInvalidDeviceTypeV7 = {
279 {.base = {.dest_device = kInvalidHalDevice}}};
280 EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataFromHal(halInvalidDeviceType, &invalidDeviceType));
281 EXPECT_EQ(BAD_VALUE,
282 CoreUtils::sinkMetadataFromHalV7(halInvalidDeviceTypeV7,
283 false /*ignoreNonVendorTags*/, &invalidDeviceType));
284 EXPECT_EQ(BAD_VALUE,
285 CoreUtils::sinkMetadataFromHalV7(halInvalidDeviceTypeV7, true /*ignoreNonVendorTags*/,
286 &invalidDeviceType));
287 std::vector<record_track_metadata_v7_t> halInvalidChannelMaskV7 = {
288 {.channel_mask = kInvalidHalChannelMask}};
289 EXPECT_EQ(BAD_VALUE,
290 CoreUtils::sinkMetadataFromHalV7(halInvalidChannelMaskV7,
291 false /*ignoreNonVendorTags*/, &invalidChannelMask));
292 EXPECT_EQ(BAD_VALUE,
293 CoreUtils::sinkMetadataFromHalV7(halInvalidChannelMaskV7,
294 true /*ignoreNonVendorTags*/, &invalidChannelMask));
295 std::vector<record_track_metadata_v7_t> halInvalidTagsV7 = {{.tags = "random string"}};
296 EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataFromHalV7(
297 halInvalidTagsV7, false /*ignoreNonVendorTags*/, &invalidTags));
298 // Non-vendor tags should be filtered out.
299 EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataFromHalV7(
300 halInvalidTagsV7, true /*ignoreNonVendorTags*/, &invalidTags));
301 }
302
TEST(CoreUtils,ConvertEmptySinkMetadata)303 TEST(CoreUtils, ConvertEmptySinkMetadata) {
304 SinkMetadata emptySinkMetadata;
305 std::vector<record_track_metadata_t> halEmptySinkMetadata;
306 EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataToHal(emptySinkMetadata, &halEmptySinkMetadata));
307 EXPECT_TRUE(halEmptySinkMetadata.empty());
308 SinkMetadata emptySinkMetadataBack;
309 EXPECT_EQ(NO_ERROR,
310 CoreUtils::sinkMetadataFromHal(halEmptySinkMetadata, &emptySinkMetadataBack));
311 EXPECT_EQ(emptySinkMetadata, emptySinkMetadataBack);
312 std::vector<record_track_metadata_v7_t> halEmptySinkMetadataV7;
313 EXPECT_EQ(NO_ERROR,
314 CoreUtils::sinkMetadataToHalV7(emptySinkMetadata, false /*ignoreNonVendorTags*/,
315 &halEmptySinkMetadataV7));
316 EXPECT_TRUE(halEmptySinkMetadataV7.empty());
317 SinkMetadata emptySinkMetadataBackFromV7;
318 EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataFromHalV7(halEmptySinkMetadataV7,
319 false /*ignoreNonVendorTags*/,
320 &emptySinkMetadataBackFromV7));
321 EXPECT_EQ(emptySinkMetadata, emptySinkMetadataBackFromV7);
322 }
323
324 class SinkMetadataConvertTest : public ::testing::TestWithParam<SinkTracks> {};
325
TEST_P(SinkMetadataConvertTest,ToFromHal)326 TEST_P(SinkMetadataConvertTest, ToFromHal) {
327 SinkMetadata sinkMetadata;
328 sinkMetadata.tracks = GetParam();
329 std::vector<record_track_metadata_t> halSinkMetadata;
330 EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataToHal(sinkMetadata, &halSinkMetadata));
331 EXPECT_EQ(sinkMetadata.tracks.size(), halSinkMetadata.size());
332 SinkMetadata sinkMetadataBackTrimmed;
333 EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataFromHal(halSinkMetadata, &sinkMetadataBackTrimmed));
334 // Can't compare 'sinkMetadata' to 'sinkMetadataBackTrimmed'
335 std::vector<record_track_metadata_v7_t> halSinkMetadataV7;
336 EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataToHalV7(sinkMetadata, false /*ignoreNonVendorTags*/,
337 &halSinkMetadataV7));
338 EXPECT_EQ(sinkMetadata.tracks.size(), halSinkMetadataV7.size());
339 SinkMetadata sinkMetadataBackFromV7;
340 EXPECT_EQ(NO_ERROR,
341 CoreUtils::sinkMetadataFromHalV7(halSinkMetadataV7, false /*ignoreNonVendorTags*/,
342 &sinkMetadataBackFromV7));
343 EXPECT_EQ(sinkMetadata, sinkMetadataBackFromV7);
344 std::vector<record_track_metadata_v7_t> halSinkMetadataV7FromTrimmed;
345 EXPECT_EQ(NO_ERROR,
346 CoreUtils::sinkMetadataToHalV7(sinkMetadataBackTrimmed, false /*ignoreNonVendorTags*/,
347 &halSinkMetadataV7FromTrimmed));
348 EXPECT_EQ(sinkMetadata.tracks.size(), halSinkMetadataV7FromTrimmed.size());
349 SinkMetadata sinkMetadataBackFromV7Trimmed;
350 EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataFromHalV7(halSinkMetadataV7FromTrimmed,
351 false /*ignoreNonVendorTags*/,
352 &sinkMetadataBackFromV7Trimmed));
353 EXPECT_EQ(sinkMetadataBackTrimmed, sinkMetadataBackFromV7Trimmed);
354 }
355
356 INSTANTIATE_TEST_SUITE_P(ValidRecordTrackMetadatas, SinkMetadataConvertTest,
357 ::testing::Values(SinkTracks{generateMinimalRecordTrackMetadata()},
358 SinkTracks{generateValidRecordTrackMetadata()},
359 SinkTracks{generateValidRecordTrackMetadataWithDevice()},
360 SinkTracks{
361 generateMinimalRecordTrackMetadata(),
362 generateValidRecordTrackMetadata(),
363 generateValidRecordTrackMetadataWithDevice()}));
364
generateMinimalPlaybackTrackMetadata()365 static PlaybackTrackMetadata generateMinimalPlaybackTrackMetadata() {
366 PlaybackTrackMetadata metadata{};
367 metadata.usage = toString(xsd::AudioUsage::AUDIO_USAGE_UNKNOWN);
368 metadata.contentType = toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_UNKNOWN);
369 metadata.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_NONE);
370 return metadata;
371 }
372
generateValidPlaybackTrackMetadata()373 static PlaybackTrackMetadata generateValidPlaybackTrackMetadata() {
374 PlaybackTrackMetadata metadata = generateMinimalPlaybackTrackMetadata();
375 metadata.tags.resize(1);
376 metadata.tags[0] = "VX_GOOGLE_42";
377 metadata.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_MONO);
378 metadata.gain = 1.0;
379 return metadata;
380 }
381
382 using SourceTracks = hidl_vec<PlaybackTrackMetadata>;
383
TEST(CoreUtils,ConvertInvalidSourceMetadata)384 TEST(CoreUtils, ConvertInvalidSourceMetadata) {
385 SourceMetadata invalidUsage;
386 invalidUsage.tracks = SourceTracks{generateMinimalPlaybackTrackMetadata()};
387 invalidUsage.tracks[0].usage = "random string";
388 EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataToHal(invalidUsage, nullptr));
389 EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataToHalV7(invalidUsage,
390 false /*ignoreNonVendorTags*/, nullptr));
391 SourceMetadata invalidContentType;
392 invalidContentType.tracks = SourceTracks{generateMinimalPlaybackTrackMetadata()};
393 invalidContentType.tracks[0].contentType = "random string";
394 EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataToHal(invalidContentType, nullptr));
395 EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataToHalV7(invalidContentType,
396 false /*ignoreNonVendorTags*/, nullptr));
397 EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataToHalV7(invalidContentType,
398 true /*ignoreNonVendorTags*/, nullptr));
399 SourceMetadata invalidChannelMask;
400 invalidChannelMask.tracks = SourceTracks{generateValidPlaybackTrackMetadata()};
401 invalidChannelMask.tracks[0].channelMask = "random string";
402 // Channel mask is sliced away by 'sourceMetadataToHal'
403 EXPECT_EQ(NO_ERROR, CoreUtils::sourceMetadataToHal(invalidChannelMask, nullptr));
404 EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataToHalV7(invalidChannelMask,
405 false /*ignoreNonVendorTags*/, nullptr));
406 EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataToHalV7(invalidChannelMask,
407 true /*ignoreNonVendorTags*/, nullptr));
408 SourceMetadata invalidTags;
409 invalidTags.tracks = SourceTracks{generateValidPlaybackTrackMetadata()};
410 invalidTags.tracks[0].tags[0] = "random string";
411 // Tags are sliced away by 'sourceMetadataToHal'
412 EXPECT_EQ(NO_ERROR, CoreUtils::sourceMetadataToHal(invalidTags, nullptr));
413 EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataToHalV7(invalidTags,
414 false /*ignoreNonVendorTags*/, nullptr));
415 // Non-vendor tags should be filtered out.
416 EXPECT_EQ(NO_ERROR,
417 CoreUtils::sourceMetadataToHalV7(invalidTags, true /*ignoreNonVendorTags*/, nullptr));
418
419 // Verify that a default-initialized metadata is valid.
420 std::vector<playback_track_metadata_t> halValid(1, playback_track_metadata_t{});
421 std::vector<playback_track_metadata_v7_t> halValidV7(1, playback_track_metadata_v7_t{});
422 SourceMetadata valid;
423 EXPECT_EQ(NO_ERROR, CoreUtils::sourceMetadataFromHal(halValid, &valid));
424 EXPECT_EQ(NO_ERROR, CoreUtils::sourceMetadataFromHalV7(halValidV7,
425 false /*ignoreNonVendorTags*/, &valid));
426 EXPECT_EQ(NO_ERROR,
427 CoreUtils::sourceMetadataFromHalV7(halValidV7, true /*ignoreNonVendorTags*/, &valid));
428
429 std::vector<playback_track_metadata_t> halInvalidUsage = {{.usage = kInvalidHalUsage}};
430 std::vector<playback_track_metadata_v7_t> halInvalidUsageV7 = {
431 {.base = {.usage = kInvalidHalUsage}}};
432 EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataFromHal(halInvalidUsage, &invalidUsage));
433 EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataFromHalV7(
434 halInvalidUsageV7, false /*ignoreNonVendorTags*/, &invalidUsage));
435 EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataFromHalV7(
436 halInvalidUsageV7, true /*ignoreNonVendorTags*/, &invalidUsage));
437 std::vector<playback_track_metadata_t> halInvalidContentType = {
438 {.content_type = kInvalidHalContentType}};
439 std::vector<playback_track_metadata_v7_t> halInvalidContentTypeV7 = {
440 {.base = {.content_type = kInvalidHalContentType}}};
441 EXPECT_EQ(BAD_VALUE,
442 CoreUtils::sourceMetadataFromHal(halInvalidContentType, &invalidContentType));
443 EXPECT_EQ(BAD_VALUE,
444 CoreUtils::sourceMetadataFromHalV7(
445 halInvalidContentTypeV7, false /*ignoreNonVendorTags*/, &invalidContentType));
446 EXPECT_EQ(BAD_VALUE,
447 CoreUtils::sourceMetadataFromHalV7(
448 halInvalidContentTypeV7, true /*ignoreNonVendorTags*/, &invalidContentType));
449 std::vector<playback_track_metadata_v7_t> halInvalidChannelMaskV7 = {
450 {.channel_mask = kInvalidHalChannelMask}};
451 EXPECT_EQ(BAD_VALUE,
452 CoreUtils::sourceMetadataFromHalV7(
453 halInvalidChannelMaskV7, false /*ignoreNonVendorTags*/, &invalidChannelMask));
454 EXPECT_EQ(BAD_VALUE,
455 CoreUtils::sourceMetadataFromHalV7(
456 halInvalidChannelMaskV7, true /*ignoreNonVendorTags*/, &invalidChannelMask));
457 std::vector<playback_track_metadata_v7_t> halInvalidTagsV7 = {{.tags = "random string"}};
458 EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataFromHalV7(
459 halInvalidTagsV7, false /*ignoreNonVendorTags*/, &invalidTags));
460 // Non-vendor tags should be filtered out.
461 EXPECT_EQ(NO_ERROR, CoreUtils::sourceMetadataFromHalV7(
462 halInvalidTagsV7, true /*ignoreNonVendorTags*/, &invalidTags));
463 }
464
TEST(CoreUtils,ConvertEmptySourceMetadata)465 TEST(CoreUtils, ConvertEmptySourceMetadata) {
466 SourceMetadata emptySourceMetadata;
467 std::vector<playback_track_metadata_t> halEmptySourceMetadata;
468 EXPECT_EQ(NO_ERROR,
469 CoreUtils::sourceMetadataToHal(emptySourceMetadata, &halEmptySourceMetadata));
470 EXPECT_TRUE(halEmptySourceMetadata.empty());
471 SourceMetadata emptySourceMetadataBack;
472 EXPECT_EQ(NO_ERROR,
473 CoreUtils::sourceMetadataFromHal(halEmptySourceMetadata, &emptySourceMetadataBack));
474 EXPECT_EQ(emptySourceMetadata, emptySourceMetadataBack);
475 std::vector<playback_track_metadata_v7_t> halEmptySourceMetadataV7;
476 EXPECT_EQ(NO_ERROR,
477 CoreUtils::sourceMetadataToHalV7(emptySourceMetadata, false /*ignoreNonVendorTags*/,
478 &halEmptySourceMetadataV7));
479 EXPECT_TRUE(halEmptySourceMetadataV7.empty());
480 SourceMetadata emptySourceMetadataBackFromV7;
481 EXPECT_EQ(NO_ERROR, CoreUtils::sourceMetadataFromHalV7(halEmptySourceMetadataV7,
482 false /*ignoreNonVendorTags*/,
483 &emptySourceMetadataBackFromV7));
484 EXPECT_EQ(emptySourceMetadata, emptySourceMetadataBackFromV7);
485 }
486
487 class SourceMetadataConvertTest : public ::testing::TestWithParam<SourceTracks> {};
488
TEST_P(SourceMetadataConvertTest,ToFromHal)489 TEST_P(SourceMetadataConvertTest, ToFromHal) {
490 SourceMetadata sourceMetadata;
491 sourceMetadata.tracks = GetParam();
492 std::vector<playback_track_metadata_t> halSourceMetadata;
493 EXPECT_EQ(NO_ERROR, CoreUtils::sourceMetadataToHal(sourceMetadata, &halSourceMetadata));
494 EXPECT_EQ(sourceMetadata.tracks.size(), halSourceMetadata.size());
495 SourceMetadata sourceMetadataBackTrimmed;
496 EXPECT_EQ(NO_ERROR,
497 CoreUtils::sourceMetadataFromHal(halSourceMetadata, &sourceMetadataBackTrimmed));
498 // Can't compare 'sourceMetadata' to 'sourceMetadataBackTrimmed'
499 std::vector<playback_track_metadata_v7_t> halSourceMetadataV7;
500 EXPECT_EQ(NO_ERROR,
501 CoreUtils::sourceMetadataToHalV7(sourceMetadata, false /*ignoreNonVendorTags*/,
502 &halSourceMetadataV7));
503 EXPECT_EQ(sourceMetadata.tracks.size(), halSourceMetadataV7.size());
504 SourceMetadata sourceMetadataBackFromV7;
505 EXPECT_EQ(NO_ERROR,
506 CoreUtils::sourceMetadataFromHalV7(halSourceMetadataV7, false /*ignoreNonVendorTags*/,
507 &sourceMetadataBackFromV7));
508 EXPECT_EQ(sourceMetadata, sourceMetadataBackFromV7);
509 std::vector<playback_track_metadata_v7_t> halSourceMetadataV7FromTrimmed;
510 EXPECT_EQ(NO_ERROR, CoreUtils::sourceMetadataToHalV7(sourceMetadataBackTrimmed,
511 false /*ignoreNonVendorTags*/,
512 &halSourceMetadataV7FromTrimmed));
513 EXPECT_EQ(sourceMetadata.tracks.size(), halSourceMetadataV7FromTrimmed.size());
514 SourceMetadata sourceMetadataBackFromV7Trimmed;
515 EXPECT_EQ(NO_ERROR, CoreUtils::sourceMetadataFromHalV7(halSourceMetadataV7FromTrimmed,
516 false /*ignoreNonVendorTags*/,
517 &sourceMetadataBackFromV7Trimmed));
518 EXPECT_EQ(sourceMetadataBackTrimmed, sourceMetadataBackFromV7Trimmed);
519 }
520
521 INSTANTIATE_TEST_SUITE_P(ValidPlaybackTrackMetadatas, SourceMetadataConvertTest,
522 ::testing::Values(SourceTracks{generateMinimalPlaybackTrackMetadata()},
523 SourceTracks{generateValidPlaybackTrackMetadata()},
524 SourceTracks{generateMinimalPlaybackTrackMetadata(),
525 generateValidPlaybackTrackMetadata()}));
526