1 /*
2 * Copyright (C) 2023 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 #define LOG_TAG "AidlConversionNdkTests"
17 #include <iostream>
18 #include <type_traits>
19
20 #include <gtest/gtest.h>
21
22 #include <media/AidlConversionCppNdk.h>
23 #include <media/AidlConversionNdk.h>
24
25 namespace {
26 template<typename> struct mf_traits {};
27 template<class T, class U> struct mf_traits<U T::*> {
28 using member_type = U;
29 };
30 } // namespace
31
32 // Provide value printers for types generated from AIDL
33 // They need to be in the same namespace as the types we intend to print
34 namespace aidl::android::hardware::audio::common {
35 template <typename P>
36 std::enable_if_t<std::is_function_v<typename mf_traits<decltype(&P::toString)>::member_type>,
operator <<(std::ostream & os,const P & p)37 std::ostream&> operator<<(std::ostream& os, const P& p) {
38 return os << p.toString();
39 }
40 template <typename E>
operator <<(std::ostream & os,const E & e)41 std::enable_if_t<std::is_enum_v<E>, std::ostream&> operator<<(std::ostream& os, const E& e) {
42 return os << toString(e);
43 }
44 } // namespace aidl::android::hardware::audio::common
45
46 using aidl::android::hardware::audio::common::PlaybackTrackMetadata;
47 using aidl::android::hardware::audio::common::RecordTrackMetadata;
48 using aidl::android::media::audio::common::AudioSource;
49 using aidl::android::media::audio::common::AudioUsage;
50 using namespace aidl::android; // for conversion functions
51
TEST(AudioPlaybackTrackMetadata,Aidl2Legacy2Aidl)52 TEST(AudioPlaybackTrackMetadata, Aidl2Legacy2Aidl) {
53 const PlaybackTrackMetadata initial{ .usage = AudioUsage::UNKNOWN };
54 auto conv = aidl2legacy_PlaybackTrackMetadata_playback_track_metadata_v7(initial);
55 ASSERT_TRUE(conv.ok());
56 auto convBack = legacy2aidl_playback_track_metadata_v7_PlaybackTrackMetadata(conv.value());
57 ASSERT_TRUE(convBack.ok());
58 EXPECT_EQ(initial, convBack.value());
59 }
60
TEST(AudioPlaybackTrackMetadata,NonVendorTags)61 TEST(AudioPlaybackTrackMetadata, NonVendorTags) {
62 PlaybackTrackMetadata initial{ .usage = AudioUsage::UNKNOWN };
63 initial.tags.emplace_back("random string"); // Must be filtered out.
64 initial.tags.emplace_back("VX_GOOGLE_42");
65 auto conv = aidl2legacy_PlaybackTrackMetadata_playback_track_metadata_v7(initial);
66 ASSERT_TRUE(conv.ok());
67 auto convBack = legacy2aidl_playback_track_metadata_v7_PlaybackTrackMetadata(conv.value());
68 ASSERT_TRUE(convBack.ok());
69 ASSERT_EQ(1, convBack.value().tags.size());
70 EXPECT_EQ(initial.tags[1], convBack.value().tags[0]);
71 }
72
TEST(AudioRecordTrackMetadata,Aidl2Legacy2Aidl)73 TEST(AudioRecordTrackMetadata, Aidl2Legacy2Aidl) {
74 const RecordTrackMetadata initial{ .source = AudioSource::DEFAULT };
75 auto conv = aidl2legacy_RecordTrackMetadata_record_track_metadata_v7(initial);
76 ASSERT_TRUE(conv.ok());
77 auto convBack = legacy2aidl_record_track_metadata_v7_RecordTrackMetadata(conv.value());
78 ASSERT_TRUE(convBack.ok());
79 EXPECT_EQ(initial, convBack.value());
80 }
81
TEST(AudioRecordTrackMetadata,NonVendorTags)82 TEST(AudioRecordTrackMetadata, NonVendorTags) {
83 RecordTrackMetadata initial{ .source = AudioSource::DEFAULT };
84 initial.tags.emplace_back("random string"); // Must be filtered out.
85 initial.tags.emplace_back("VX_GOOGLE_42");
86 auto conv = aidl2legacy_RecordTrackMetadata_record_track_metadata_v7(initial);
87 ASSERT_TRUE(conv.ok());
88 auto convBack = legacy2aidl_record_track_metadata_v7_RecordTrackMetadata(conv.value());
89 ASSERT_TRUE(convBack.ok());
90 ASSERT_EQ(1, convBack.value().tags.size());
91 EXPECT_EQ(initial.tags[1], convBack.value().tags[0]);
92 }
93
94 class AudioTagsRoundTripTest : public testing::TestWithParam<std::vector<std::string>>
95 {
96 };
TEST_P(AudioTagsRoundTripTest,Aidl2Legacy2Aidl)97 TEST_P(AudioTagsRoundTripTest, Aidl2Legacy2Aidl) {
98 const auto& initial = GetParam();
99 auto conv = aidl2legacy_AudioTags_string(initial);
100 ASSERT_TRUE(conv.ok());
101 auto convBack = legacy2aidl_string_AudioTags(conv.value());
102 ASSERT_TRUE(convBack.ok());
103 EXPECT_EQ(initial, convBack.value());
104 }
105 INSTANTIATE_TEST_SUITE_P(AudioTagsRoundTrip, AudioTagsRoundTripTest,
106 testing::Values(std::vector<std::string>{},
107 std::vector<std::string>{"VX_GOOGLE_41"},
108 std::vector<std::string>{"VX_GOOGLE_41", "VX_GOOGLE_42"}));
109
TEST(AudioTags,NonVendorTagsAllowed)110 TEST(AudioTags, NonVendorTagsAllowed) {
111 const std::string separator(1, AUDIO_ATTRIBUTES_TAGS_SEPARATOR);
112 const std::vector<std::string> initial{"random_string", "VX_GOOGLE_42"};
113 auto conv = aidl2legacy_AudioTags_string(initial);
114 ASSERT_TRUE(conv.ok());
115 EXPECT_EQ("random_string" + separator + "VX_GOOGLE_42", conv.value());
116 }
117
TEST(AudioTags,IllFormedAidlTag)118 TEST(AudioTags, IllFormedAidlTag) {
119 const std::string separator(1, AUDIO_ATTRIBUTES_TAGS_SEPARATOR);
120 {
121 const std::vector<std::string> initial{"VX_GOOGLE" + separator + "42", "VX_GOOGLE_42"};
122 auto conv = aidl2legacy_AudioTags_string(initial);
123 if (conv.ok()) {
124 EXPECT_EQ("VX_GOOGLE_42", conv.value());
125 }
126 // Failing this conversion is also OK. The result depends on whether the conversion
127 // only passes through vendor tags.
128 }
129 {
130 const std::vector<std::string> initial{
131 "random_string", "random" + separator + "string", "VX_GOOGLE_42"};
132 auto conv = aidl2legacy_AudioTags_string(initial);
133 if (conv.ok()) {
134 EXPECT_EQ("VX_GOOGLE_42", conv.value());
135 }
136 }
137 }
138