xref: /aosp_15_r20/frameworks/av/media/libaaudio/tests/test_attributes.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
1 /*
2  * Copyright (C) 2017 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 // Test AAudio attributes such as Usage, ContentType, InputPreset and Tags.
18 
19 // TODO Many of these tests are duplicates of CTS tests in
20 // "test_aaudio_attributes.cpp". That other file is more current.
21 // So these tests could be deleted.
22 // Also note audio attributes tags, which is system api, it cannot be tested
23 // from the CTS. In that case, please do not delete audio attributes tags test.
24 
25 #include <algorithm>
26 #include <memory>
27 #include <stdio.h>
28 #include <unistd.h>
29 #include <vector>
30 
31 #include <aaudio/AAudio.h>
32 #include <gtest/gtest.h>
33 #include <system/audio.h>
34 #include <system/aaudio/AAudio.h>
35 
36 constexpr int64_t kNanosPerSecond = 1000000000;
37 constexpr int kNumFrames = 256;
38 constexpr int kChannelCount = 2;
39 
40 constexpr int32_t DONT_SET = -1000;
41 
checkAttributes(aaudio_performance_mode_t perfMode,aaudio_usage_t usage,aaudio_content_type_t contentType,std::vector<const char * > * tags=nullptr,aaudio_input_preset_t preset=DONT_SET,aaudio_allowed_capture_policy_t capturePolicy=DONT_SET,int privacyMode=DONT_SET,aaudio_direction_t direction=AAUDIO_DIRECTION_OUTPUT,const char * tagToBeCleared="TagsToBeCleared")42 static void checkAttributes(aaudio_performance_mode_t perfMode,
43                             aaudio_usage_t usage,
44                             aaudio_content_type_t contentType,
45                             std::vector<const char*>* tags = nullptr,
46                             aaudio_input_preset_t preset = DONT_SET,
47                             aaudio_allowed_capture_policy_t capturePolicy = DONT_SET,
48                             int privacyMode = DONT_SET,
49                             aaudio_direction_t direction = AAUDIO_DIRECTION_OUTPUT,
50                             const char* tagToBeCleared = "TagsToBeCleared") {
51 
52     std::unique_ptr<float[]> buffer(new float[kNumFrames * kChannelCount]);
53 
54     AAudioStreamBuilder *aaudioBuilder = nullptr;
55     AAudioStream *aaudioStream = nullptr;
56     aaudio_result_t expectedAddTagResult = AAUDIO_OK;
57 
58     // Use an AAudioStreamBuilder to contain requested parameters.
59     ASSERT_EQ(AAUDIO_OK, AAudio_createStreamBuilder(&aaudioBuilder));
60 
61     // Request stream properties.
62     AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, perfMode);
63     AAudioStreamBuilder_setDirection(aaudioBuilder, direction);
64 
65     // Set the attribute in the builder.
66     if (usage != DONT_SET) {
67         AAudioStreamBuilder_setUsage(aaudioBuilder, usage);
68     }
69     if (contentType != DONT_SET) {
70         AAudioStreamBuilder_setContentType(aaudioBuilder, contentType);
71     }
72     std::set<std::string> addedTags;
73     if (tags != nullptr) {
74         EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_addTag(aaudioBuilder, tagToBeCleared));
75         AAudioStreamBuilder_clearTags(aaudioBuilder);
76         int totalLength = 0;
77         for (int i = 0; i < tags->size(); ++i) {
78             if (tags->at(i) == nullptr) {
79                 EXPECT_EQ(AAUDIO_ERROR_ILLEGAL_ARGUMENT,
80                           AAudioStreamBuilder_addTag(aaudioBuilder, tags->at(i)));
81                 continue;
82             }
83             // When sending all tags across the framework and the HAL, all tags are joined as a
84             // string. In that case, a delimiter will be added if the tag is not the last added
85             // tag or NULL terminator will be added if the tag is the last added tag.
86             int lengthToAdd = strlen(tags->at(i)) + 1;
87             totalLength += lengthToAdd;
88             aaudio_result_t result = AAudioStreamBuilder_addTag(aaudioBuilder, tags->at(i));
89             expectedAddTagResult = (totalLength > AUDIO_ATTRIBUTES_TAGS_MAX_SIZE) ?
90                                    AAUDIO_ERROR_OUT_OF_RANGE : AAUDIO_OK;
91             EXPECT_EQ(result, expectedAddTagResult) << "total length=" << totalLength;
92             if (expectedAddTagResult != AAUDIO_OK) {
93                 totalLength -= lengthToAdd;
94             } else {
95                 addedTags.insert(tags->at(i));
96             }
97         }
98     }
99     if (preset != DONT_SET) {
100         AAudioStreamBuilder_setInputPreset(aaudioBuilder, preset);
101     }
102     if (capturePolicy != DONT_SET) {
103         AAudioStreamBuilder_setAllowedCapturePolicy(aaudioBuilder, capturePolicy);
104     }
105     if (privacyMode != DONT_SET) {
106         AAudioStreamBuilder_setPrivacySensitive(aaudioBuilder, (bool)privacyMode);
107     }
108 
109     // Create an AAudioStream using the Builder.
110     ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream));
111     AAudioStreamBuilder_delete(aaudioBuilder);
112 
113     // Make sure we get the same attributes back from the stream.
114     aaudio_usage_t expectedUsage =
115             (usage == DONT_SET || usage == AAUDIO_UNSPECIFIED)
116             ? AAUDIO_USAGE_MEDIA // default
117             : usage;
118     EXPECT_EQ(expectedUsage, AAudioStream_getUsage(aaudioStream));
119 
120     aaudio_content_type_t expectedContentType =
121             (contentType == DONT_SET || contentType == AAUDIO_UNSPECIFIED)
122             ? AAUDIO_CONTENT_TYPE_MUSIC // default
123             : contentType;
124     EXPECT_EQ(expectedContentType, AAudioStream_getContentType(aaudioStream));
125 
126     char** readTags = nullptr;
127     const int32_t numOfTagsRead = AAudioStream_obtainTags(aaudioStream, &readTags);
128     EXPECT_EQ(addedTags.size(), numOfTagsRead);
129     EXPECT_EQ(numOfTagsRead == 0, readTags == nullptr);
130     std::set<std::string> readTagsSet;
131     for (int i = 0; i < numOfTagsRead; ++i) {
132         readTagsSet.insert(readTags[i]);
133     }
134     EXPECT_EQ(addedTags, readTagsSet);
135     AAudioStream_releaseTags(aaudioStream, readTags);
136 
137     aaudio_input_preset_t expectedPreset =
138             (preset == DONT_SET || preset == AAUDIO_UNSPECIFIED)
139             ? AAUDIO_INPUT_PRESET_VOICE_RECOGNITION // default
140             : preset;
141     EXPECT_EQ(expectedPreset, AAudioStream_getInputPreset(aaudioStream));
142 
143     aaudio_allowed_capture_policy_t expectedCapturePolicy =
144             (capturePolicy == DONT_SET || capturePolicy == AAUDIO_UNSPECIFIED)
145             ? AAUDIO_ALLOW_CAPTURE_BY_ALL // default
146             : capturePolicy;
147     EXPECT_EQ(expectedCapturePolicy, AAudioStream_getAllowedCapturePolicy(aaudioStream));
148 
149     bool expectedPrivacyMode =
150             (privacyMode == DONT_SET) ?
151                 ((preset == AAUDIO_INPUT_PRESET_VOICE_COMMUNICATION
152                     || preset == AAUDIO_INPUT_PRESET_CAMCORDER) ? true : false) :
153                 privacyMode;
154     EXPECT_EQ(expectedPrivacyMode, AAudioStream_isPrivacySensitive(aaudioStream));
155 
156     EXPECT_EQ(AAUDIO_OK, AAudioStream_requestStart(aaudioStream));
157 
158     if (direction == AAUDIO_DIRECTION_INPUT) {
159         EXPECT_EQ(kNumFrames,
160                   AAudioStream_read(aaudioStream, buffer.get(), kNumFrames, kNanosPerSecond));
161     } else {
162         EXPECT_EQ(kNumFrames,
163                   AAudioStream_write(aaudioStream, buffer.get(), kNumFrames, kNanosPerSecond));
164     }
165 
166     EXPECT_EQ(AAUDIO_OK, AAudioStream_requestStop(aaudioStream));
167 
168     EXPECT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream));
169 }
170 
171 static const aaudio_usage_t sUsages[] = {
172     DONT_SET,
173     AAUDIO_UNSPECIFIED,
174     AAUDIO_USAGE_MEDIA,
175     AAUDIO_USAGE_VOICE_COMMUNICATION,
176     AAUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING,
177     AAUDIO_USAGE_ALARM,
178     AAUDIO_USAGE_NOTIFICATION,
179     AAUDIO_USAGE_NOTIFICATION_RINGTONE,
180     AAUDIO_USAGE_NOTIFICATION_EVENT,
181     AAUDIO_USAGE_ASSISTANCE_ACCESSIBILITY,
182     AAUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
183     AAUDIO_USAGE_ASSISTANCE_SONIFICATION,
184     AAUDIO_USAGE_GAME,
185     AAUDIO_USAGE_ASSISTANT,
186     // Note that the AAUDIO_SYSTEM_USAGE_* values requires special permission.
187 };
188 
189 static const std::string oversizedTags2 = std::string(AUDIO_ATTRIBUTES_TAGS_MAX_SIZE + 1, 'A');
190 static const std::string oversizedTags = std::string(AUDIO_ATTRIBUTES_TAGS_MAX_SIZE, 'B');
191 static const std::string maxSizeTags = std::string(AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1, 'C');
192 
193 static const int TOTAL_TAGS = 7;
194 static const char * const sTags[TOTAL_TAGS] = {
195     nullptr,
196     "",
197     "oem=routing_extension",
198     "VX_OEM_ROUTING_EXTENSION",
199     maxSizeTags.c_str(),
200     // intentionnaly use oversized tags
201     oversizedTags.c_str(),
202     oversizedTags2.c_str()
203 };
204 
205 static const aaudio_content_type_t sContentypes[] = {
206     DONT_SET,
207     AAUDIO_UNSPECIFIED,
208     AAUDIO_CONTENT_TYPE_SPEECH,
209     AAUDIO_CONTENT_TYPE_MUSIC,
210     AAUDIO_CONTENT_TYPE_MOVIE,
211     AAUDIO_CONTENT_TYPE_SONIFICATION
212 };
213 
214 static const aaudio_input_preset_t sInputPresets[] = {
215     DONT_SET,
216     AAUDIO_UNSPECIFIED,
217     AAUDIO_INPUT_PRESET_GENERIC,
218     AAUDIO_INPUT_PRESET_CAMCORDER,
219     AAUDIO_INPUT_PRESET_VOICE_RECOGNITION,
220     AAUDIO_INPUT_PRESET_VOICE_COMMUNICATION,
221     AAUDIO_INPUT_PRESET_UNPROCESSED,
222     AAUDIO_INPUT_PRESET_VOICE_PERFORMANCE,
223 };
224 
225 static const aaudio_input_preset_t sAllowCapturePolicies[] = {
226     DONT_SET,
227     AAUDIO_UNSPECIFIED,
228     AAUDIO_ALLOW_CAPTURE_BY_ALL,
229     AAUDIO_ALLOW_CAPTURE_BY_SYSTEM,
230     AAUDIO_ALLOW_CAPTURE_BY_NONE,
231 };
232 
233 static const int sPrivacyModes[] = {
234     DONT_SET,
235     false,
236     true,
237 };
238 
checkAttributesUsage(aaudio_performance_mode_t perfMode)239 static void checkAttributesUsage(aaudio_performance_mode_t perfMode) {
240     for (aaudio_usage_t usage : sUsages) {
241         checkAttributes(perfMode, usage, DONT_SET);
242     }
243 }
244 
checkAttributesContentType(aaudio_performance_mode_t perfMode)245 static void checkAttributesContentType(aaudio_performance_mode_t perfMode) {
246     for (aaudio_content_type_t contentType : sContentypes) {
247         checkAttributes(perfMode, DONT_SET, contentType);
248     }
249 }
250 
checkAttributesTags(aaudio_performance_mode_t perfMode)251 static void checkAttributesTags(aaudio_performance_mode_t perfMode) {
252     checkAttributes(perfMode, DONT_SET, DONT_SET, nullptr /*tags*/);
253     for (int i = 0; i < TOTAL_TAGS; ++i) {
254         std::vector<const char*> tags = {sTags[i]};
255         if (i > 0) {
256             tags.push_back(sTags[i-1]);
257         }
258         checkAttributes(perfMode, DONT_SET, DONT_SET, &tags);
259     }
260 }
261 
checkAttributesInputPreset(aaudio_performance_mode_t perfMode)262 static void checkAttributesInputPreset(aaudio_performance_mode_t perfMode) {
263     for (aaudio_input_preset_t inputPreset : sInputPresets) {
264         checkAttributes(perfMode,
265                         DONT_SET,
266                         DONT_SET,
267                         nullptr,
268                         inputPreset,
269                         DONT_SET,
270                         DONT_SET,
271                         AAUDIO_DIRECTION_INPUT);
272     }
273 }
274 
checkAttributesAllowedCapturePolicy(aaudio_performance_mode_t perfMode)275 static void checkAttributesAllowedCapturePolicy(aaudio_performance_mode_t perfMode) {
276     for (aaudio_allowed_capture_policy_t policy : sAllowCapturePolicies) {
277         checkAttributes(perfMode,
278                         DONT_SET,
279                         DONT_SET,
280                         nullptr,
281                         DONT_SET,
282                         policy,
283                         AAUDIO_DIRECTION_INPUT);
284     }
285 }
286 
checkAttributesPrivacySensitive(aaudio_performance_mode_t perfMode)287 static void checkAttributesPrivacySensitive(aaudio_performance_mode_t perfMode) {
288     for (int privacyMode : sPrivacyModes) {
289         checkAttributes(perfMode,
290                         DONT_SET,
291                         DONT_SET,
292                         nullptr,
293                         DONT_SET,
294                         DONT_SET,
295                         privacyMode,
296                         AAUDIO_DIRECTION_INPUT);
297     }
298 }
299 
TEST(test_attributes,aaudio_usage_perfnone)300 TEST(test_attributes, aaudio_usage_perfnone) {
301     checkAttributesUsage(AAUDIO_PERFORMANCE_MODE_NONE);
302 }
303 
TEST(test_attributes,aaudio_content_type_perfnone)304 TEST(test_attributes, aaudio_content_type_perfnone) {
305     checkAttributesContentType(AAUDIO_PERFORMANCE_MODE_NONE);
306 }
307 
TEST(test_attributes,aaudio_tags_perfnone)308 TEST(test_attributes, aaudio_tags_perfnone) {
309     checkAttributesTags(AAUDIO_PERFORMANCE_MODE_NONE);
310 }
311 
TEST(test_attributes,aaudio_input_preset_perfnone)312 TEST(test_attributes, aaudio_input_preset_perfnone) {
313     checkAttributesInputPreset(AAUDIO_PERFORMANCE_MODE_NONE);
314 }
315 
TEST(test_attributes,aaudio_allowed_capture_policy_perfnone)316 TEST(test_attributes, aaudio_allowed_capture_policy_perfnone) {
317     checkAttributesAllowedCapturePolicy(AAUDIO_PERFORMANCE_MODE_NONE);
318 }
319 
TEST(test_attributes,aaudio_usage_lowlat)320 TEST(test_attributes, aaudio_usage_lowlat) {
321     checkAttributesUsage(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
322 }
323 
TEST(test_attributes,aaudio_content_type_lowlat)324 TEST(test_attributes, aaudio_content_type_lowlat) {
325     checkAttributesContentType(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
326 }
327 
TEST(test_attributes,aaudio_tags_lowlat)328 TEST(test_attributes, aaudio_tags_lowlat) {
329     checkAttributesTags(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
330 }
331 
TEST(test_attributes,aaudio_input_preset_lowlat)332 TEST(test_attributes, aaudio_input_preset_lowlat) {
333     checkAttributesInputPreset(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
334 }
335 
TEST(test_attributes,aaudio_allowed_capture_policy_lowlat)336 TEST(test_attributes, aaudio_allowed_capture_policy_lowlat) {
337     checkAttributesAllowedCapturePolicy(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
338 }
339 
TEST(test_attributes,aaudio_allowed_privacy_sensitive_lowlat)340 TEST(test_attributes, aaudio_allowed_privacy_sensitive_lowlat) {
341     checkAttributesPrivacySensitive(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
342 }
343