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