1 /*
2  * Copyright (C) 2018 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 and InputPreset.
18 
19 #include <cctype>
20 #include <stdio.h>
21 #include <sstream>
22 #include <string>
23 #include <unistd.h>
24 #include <utility>
25 
26 #include <aaudio/AAudio.h>
27 #include <gtest/gtest.h>
28 
29 #include "utils.h"
30 
31 constexpr int64_t kNanosPerSecond = 1000000000;
32 constexpr int kNumFrames = 256;
33 constexpr int kChannelCount = 2;
34 
35 constexpr int32_t DONT_SET = -1000;
36 constexpr const char *DONT_SET_STR = "do_not_set";
37 
38 #define IS_SPATIALIZED_FALSE (AAUDIO_UNSPECIFIED + 1)
39 #define IS_SPATIALIZED_TRUE  (AAUDIO_UNSPECIFIED + 2)
40 
41 #define IS_PRIVACY_SENSITIVE_FALSE (AAUDIO_UNSPECIFIED + 1)
42 #define IS_PRIVACY_SENSITIVE_TRUE (AAUDIO_UNSPECIFIED + 2)
43 
printPerformanceModeToTestName(aaudio_performance_mode_t performanceMode,std::stringstream & ss)44 static void printPerformanceModeToTestName(aaudio_performance_mode_t performanceMode,
45                                                   std::stringstream& ss) {
46     ss << "perf_";
47     switch (performanceMode) {
48         case AAUDIO_PERFORMANCE_MODE_NONE:
49             ss << "none";
50             break;
51         case AAUDIO_PERFORMANCE_MODE_POWER_SAVING:
52             ss << "power_saving";
53             break;
54         case AAUDIO_PERFORMANCE_MODE_LOW_LATENCY:
55             ss << "low_latency";
56             break;
57         default:
58             ss << "unknown";
59             break;
60     }
61 }
62 
printStrToTestName(const char * str,std::stringstream & ss)63 static void printStrToTestName(const char* str, std::stringstream& ss) {
64     if (str == nullptr) {
65         ss << "null";
66         return;
67     }
68     for (size_t i = 0; i < strlen(str); ++i) {
69         ss << (isalnum(str[i]) ? str[i] : '_');
70     }
71 }
72 
73 class AAudioAttributesTestBase : public AAudioCtsBase {
74 protected:
75     void checkAttributes();
76 
77     aaudio_performance_mode_t mPerfMode = AAUDIO_PERFORMANCE_MODE_NONE;
78     aaudio_usage_t mUsage = DONT_SET;
79     aaudio_content_type_t mContentType = DONT_SET;
80     aaudio_spatialization_behavior_t mSpatializationBehavior = DONT_SET;
81     int mIsContentSpatialized = DONT_SET;
82     aaudio_input_preset_t mPreset = DONT_SET;
83     aaudio_allowed_capture_policy_t mCapturePolicy = DONT_SET;
84     int mIsPrivacySensitive = DONT_SET;
85     aaudio_direction_t mDirection = AAUDIO_DIRECTION_OUTPUT;
86     const char *mPackageName = DONT_SET_STR;
87     const char *mAttributionTag = DONT_SET_STR;
88 };
89 
checkAttributes()90 void AAudioAttributesTestBase::checkAttributes() {
91     if (mDirection == AAUDIO_DIRECTION_INPUT
92             && !deviceSupportsFeature(FEATURE_RECORDING)) return;
93     else if (mDirection == AAUDIO_DIRECTION_OUTPUT
94             && !deviceSupportsFeature(FEATURE_PLAYBACK)) return;
95 
96     std::unique_ptr<float[]> buffer(new float[kNumFrames * kChannelCount]);
97 
98     AAudioStreamBuilder *aaudioBuilder = nullptr;
99     AAudioStream *aaudioStream = nullptr;
100 
101     // Use an AAudioStreamBuilder to contain requested parameters.
102     ASSERT_EQ(AAUDIO_OK, AAudio_createStreamBuilder(&aaudioBuilder));
103 
104     // Request stream properties.
105     AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, mPerfMode);
106     AAudioStreamBuilder_setDirection(aaudioBuilder, mDirection);
107 
108     // Set the attribute in the builder.
109     if (mUsage != DONT_SET) {
110         AAudioStreamBuilder_setUsage(aaudioBuilder, mUsage);
111     }
112     if (mContentType != DONT_SET) {
113         AAudioStreamBuilder_setContentType(aaudioBuilder, mContentType);
114     }
115     if (mSpatializationBehavior != DONT_SET) {
116         AAudioStreamBuilder_setSpatializationBehavior(aaudioBuilder, mSpatializationBehavior);
117     }
118     if (mIsContentSpatialized != DONT_SET) {
119         AAudioStreamBuilder_setIsContentSpatialized(aaudioBuilder,
120                                                     mIsContentSpatialized == IS_SPATIALIZED_TRUE);
121     }
122     if (mPreset != DONT_SET) {
123         AAudioStreamBuilder_setInputPreset(aaudioBuilder, mPreset);
124     }
125     if (mCapturePolicy != DONT_SET) {
126         AAudioStreamBuilder_setAllowedCapturePolicy(aaudioBuilder, mCapturePolicy);
127     }
128     if (mIsPrivacySensitive != DONT_SET) {
129         AAudioStreamBuilder_setPrivacySensitive(aaudioBuilder,
130                                                 mIsPrivacySensitive == IS_PRIVACY_SENSITIVE_TRUE);
131     }
132     if (mPackageName != DONT_SET_STR) {
133         AAudioStreamBuilder_setPackageName(aaudioBuilder, mPackageName);
134     }
135     if (mAttributionTag != DONT_SET_STR) {
136         AAudioStreamBuilder_setAttributionTag(aaudioBuilder, mAttributionTag);
137     }
138 
139     // Create an AAudioStream using the Builder.
140     ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream));
141     AAudioStreamBuilder_delete(aaudioBuilder);
142 
143     // Make sure we get the same attributes back from the stream.
144     aaudio_usage_t expectedUsage =
145             (mUsage == DONT_SET || mUsage == AAUDIO_UNSPECIFIED)
146             ? AAUDIO_USAGE_MEDIA // default
147             : mUsage;
148     EXPECT_EQ(expectedUsage, AAudioStream_getUsage(aaudioStream));
149 
150     aaudio_content_type_t expectedContentType =
151             (mContentType == DONT_SET || mContentType == AAUDIO_UNSPECIFIED)
152             ? AAUDIO_CONTENT_TYPE_MUSIC // default
153             : mContentType;
154     EXPECT_EQ(expectedContentType, AAudioStream_getContentType(aaudioStream));
155 
156     if (mPerfMode == AAUDIO_PERFORMANCE_MODE_NONE) {
157         aaudio_spatialization_behavior_t expectedBehavior =
158                 (mSpatializationBehavior == DONT_SET ||
159                  mSpatializationBehavior == AAUDIO_UNSPECIFIED)
160                         ? AAUDIO_SPATIALIZATION_BEHAVIOR_AUTO // default
161                         : mSpatializationBehavior;
162         EXPECT_EQ(expectedBehavior, AAudioStream_getSpatializationBehavior(aaudioStream));
163 
164         bool expectedIsContentSpatialized =
165                 (mIsContentSpatialized == DONT_SET)
166                 ? false //default
167                 : mIsContentSpatialized == IS_SPATIALIZED_TRUE;
168         EXPECT_EQ(expectedIsContentSpatialized, AAudioStream_isContentSpatialized(aaudioStream));
169     }
170 
171     aaudio_input_preset_t expectedPreset =
172             (mPreset == DONT_SET || mPreset == AAUDIO_UNSPECIFIED)
173             ? AAUDIO_INPUT_PRESET_VOICE_RECOGNITION // default
174             : mPreset;
175     EXPECT_EQ(expectedPreset, AAudioStream_getInputPreset(aaudioStream));
176 
177     aaudio_allowed_capture_policy_t expectedCapturePolicy =
178             (mCapturePolicy == DONT_SET || mCapturePolicy == AAUDIO_UNSPECIFIED)
179             ? AAUDIO_ALLOW_CAPTURE_BY_ALL // default
180             : mCapturePolicy;
181     EXPECT_EQ(expectedCapturePolicy, AAudioStream_getAllowedCapturePolicy(aaudioStream));
182 
183     bool expectedPrivacyMode =
184             (mIsPrivacySensitive == DONT_SET)
185                 ? ((mPreset == AAUDIO_INPUT_PRESET_VOICE_COMMUNICATION
186                     || mPreset == AAUDIO_INPUT_PRESET_CAMCORDER) ? true : false)
187                 : (mIsPrivacySensitive == IS_PRIVACY_SENSITIVE_TRUE);
188     EXPECT_EQ(expectedPrivacyMode, AAudioStream_isPrivacySensitive(aaudioStream));
189 
190     EXPECT_EQ(AAUDIO_OK, AAudioStream_requestStart(aaudioStream));
191 
192     if (mDirection == AAUDIO_DIRECTION_INPUT) {
193         EXPECT_EQ(kNumFrames,
194                   AAudioStream_read(aaudioStream, buffer.get(), kNumFrames, kNanosPerSecond));
195     } else {
196         EXPECT_EQ(kNumFrames,
197                   AAudioStream_write(aaudioStream, buffer.get(), kNumFrames, kNanosPerSecond));
198     }
199 
200     EXPECT_EQ(AAUDIO_OK, AAudioStream_requestStop(aaudioStream));
201 
202     EXPECT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream));
203 }
204 
205 /******************************************************************************
206  * PackageNameTest
207  *****************************************************************************/
208 
209 using PackageNameParam = std::tuple<aaudio_performance_mode_t, const char*>;
210 class PackageNameTest : public AAudioAttributesTestBase,
211                         public ::testing::WithParamInterface<PackageNameParam> {
212 public:
getTestName(const::testing::TestParamInfo<PackageNameParam> & info)213     static std::string getTestName(const ::testing::TestParamInfo<PackageNameParam>& info) {
214         std::stringstream ss;
215         printPerformanceModeToTestName(std::get<0>(info.param), ss);
216         ss << "_package_name_";
217         printStrToTestName(std::get<1>(info.param), ss);
218         return ss.str();
219     }
220 
221 protected:
222     void SetUp() override;
223 };
224 
SetUp()225 void PackageNameTest::SetUp() {
226     mPerfMode = std::get<0>(GetParam());
227     mPackageName = std::get<1>(GetParam());
228 }
229 
TEST_P(PackageNameTest,checkAttributes)230 TEST_P(PackageNameTest, checkAttributes) {
231     checkAttributes();
232 }
233 
234 INSTANTIATE_TEST_CASE_P(AAudioTestAttributes, PackageNameTest,
235         ::testing::Combine(
236                 ::testing::Values(AAUDIO_PERFORMANCE_MODE_NONE,
237                                   AAUDIO_PERFORMANCE_MODE_LOW_LATENCY),
238                 ::testing::Values(DONT_SET_STR,
239                                   "android.nativemedia.aaudio")),
240                 &PackageNameTest::getTestName);
241 
242 /******************************************************************************
243  * AttributionTagTest
244  *****************************************************************************/
245 
246 using AttributionTagParam = std::tuple<aaudio_performance_mode_t, const char*>;
247 class AttributionTagTest : public AAudioAttributesTestBase,
248                            public ::testing::WithParamInterface<AttributionTagParam> {
249 public:
getTestName(const::testing::TestParamInfo<AttributionTagParam> & info)250     static std::string getTestName(const ::testing::TestParamInfo<AttributionTagParam>& info) {
251         std::stringstream ss;
252         printPerformanceModeToTestName(std::get<0>(info.param), ss);
253         ss << "_attribution_tag_";
254         printStrToTestName(std::get<1>(info.param), ss);
255         return ss.str();
256     }
257 
258 protected:
259     void SetUp() override;
260 };
261 
SetUp()262 void AttributionTagTest::SetUp() {
263     mPerfMode = std::get<0>(GetParam());
264     mAttributionTag = std::get<1>(GetParam());
265     mDirection = AAUDIO_DIRECTION_INPUT;
266 }
267 
TEST_P(AttributionTagTest,checkAttributes)268 TEST_P(AttributionTagTest, checkAttributes) {
269     checkAttributes();
270 }
271 
272 INSTANTIATE_TEST_CASE_P(AAudioTestAttributes, AttributionTagTest,
273         ::testing::Combine(
274                 ::testing::Values(AAUDIO_PERFORMANCE_MODE_NONE,
275                                   AAUDIO_PERFORMANCE_MODE_LOW_LATENCY),
276                 ::testing::Values(DONT_SET_STR,
277                                   "validTag",
278                                   nullptr)),
279                 &AttributionTagTest::getTestName);
280 
281 /******************************************************************************
282  * UsageTest
283  *****************************************************************************/
284 
285 using UsageParam = std::tuple<aaudio_performance_mode_t, aaudio_usage_t>;
286 class UsageTest : public AAudioAttributesTestBase,
287                   public ::testing::WithParamInterface<UsageParam> {
288 public:
getTestName(const::testing::TestParamInfo<UsageParam> & info)289     static std::string getTestName(const ::testing::TestParamInfo<UsageParam>& info) {
290         std::stringstream ss;
291         printPerformanceModeToTestName(std::get<0>(info.param), ss);
292         ss << "_usage_";
293         switch (std::get<1>(info.param)) {
294             case DONT_SET:
295                 ss << "do_not_set";
296                 break;
297             case AAUDIO_UNSPECIFIED:
298                 ss << "unspecified";
299                 break;
300             case AAUDIO_USAGE_MEDIA:
301                 ss << "media";
302                 break;
303             case AAUDIO_USAGE_VOICE_COMMUNICATION:
304                 ss << "voicecomm";
305                 break;
306             case AAUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING:
307                 ss << "voicecommsig";
308                 break;
309             case AAUDIO_USAGE_ALARM:
310                 ss << "alarm";
311                 break;
312             case AAUDIO_USAGE_NOTIFICATION:
313                 ss << "notification";
314                 break;
315             case AAUDIO_USAGE_NOTIFICATION_RINGTONE:
316                 ss << "notiringtone";
317                 break;
318             case AAUDIO_USAGE_NOTIFICATION_EVENT:
319                 ss << "notievent";
320                 break;
321             case AAUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
322                 ss << "assistacc";
323                 break;
324             case AAUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
325                 ss << "assistnavgui";
326                 break;
327             case AAUDIO_USAGE_ASSISTANCE_SONIFICATION:
328                 ss << "assistsoni";
329                 break;
330             case AAUDIO_USAGE_GAME:
331                 ss << "game";
332                 break;
333             case AAUDIO_USAGE_ASSISTANT:
334                 ss << "assistant";
335                 break;
336             default:
337                 ss << "unknown";
338         }
339         return ss.str();
340     }
341 
342 protected:
343     void SetUp() override;
344 };
345 
SetUp()346 void UsageTest::SetUp() {
347     mPerfMode = std::get<0>(GetParam());
348     mUsage = std::get<1>(GetParam());
349 }
350 
TEST_P(UsageTest,checkAttributes)351 TEST_P(UsageTest, checkAttributes) {
352     checkAttributes();
353 }
354 
355 INSTANTIATE_TEST_CASE_P(AAudioTestAttributes, UsageTest,
356         ::testing::Combine(
357                 ::testing::Values(AAUDIO_PERFORMANCE_MODE_NONE,
358                                   AAUDIO_PERFORMANCE_MODE_LOW_LATENCY),
359                 ::testing::Values(DONT_SET,
360                                   AAUDIO_UNSPECIFIED,
361                                   AAUDIO_USAGE_MEDIA,
362                                   AAUDIO_USAGE_VOICE_COMMUNICATION,
363                                   AAUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING,
364                                   AAUDIO_USAGE_ALARM,
365                                   AAUDIO_USAGE_NOTIFICATION,
366                                   AAUDIO_USAGE_NOTIFICATION_RINGTONE,
367                                   AAUDIO_USAGE_NOTIFICATION_EVENT,
368                                   AAUDIO_USAGE_ASSISTANCE_ACCESSIBILITY,
369                                   AAUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
370                                   AAUDIO_USAGE_ASSISTANCE_SONIFICATION,
371                                   AAUDIO_USAGE_GAME,
372                                   AAUDIO_USAGE_ASSISTANT)),
373                 &UsageTest::getTestName);
374 
375 /******************************************************************************
376  * ContentTypeTest
377  *****************************************************************************/
378 
379 using ContentTypeParam = std::tuple<aaudio_performance_mode_t, aaudio_content_type_t>;
380 class ContentTypeTest : public AAudioAttributesTestBase,
381                         public ::testing::WithParamInterface<ContentTypeParam> {
382 public:
getTestName(const::testing::TestParamInfo<ContentTypeParam> & info)383     static std::string getTestName(const ::testing::TestParamInfo<ContentTypeParam>& info) {
384         std::stringstream ss;
385         printPerformanceModeToTestName(std::get<0>(info.param), ss);
386         ss << "_content_type_";
387         switch (std::get<1>(info.param)) {
388             case DONT_SET:
389                 ss << "do_not_set";
390                 break;
391             case AAUDIO_UNSPECIFIED:
392                 ss << "unspecified";
393                 break;
394             case AAUDIO_CONTENT_TYPE_SPEECH:
395                 ss << "speech";
396                 break;
397             case AAUDIO_CONTENT_TYPE_MUSIC:
398                 ss << "music";
399                 break;
400             case AAUDIO_CONTENT_TYPE_MOVIE:
401                 ss << "movie";
402                 break;
403             case AAUDIO_CONTENT_TYPE_SONIFICATION:
404                 ss << "sonification";
405                 break;
406             default:
407                 ss << "unknown";
408                 break;
409         }
410         return ss.str();
411     }
412 
413 protected:
414     void SetUp() override;
415 };
416 
SetUp()417 void ContentTypeTest::SetUp() {
418     mPerfMode = std::get<0>(GetParam());
419     mContentType = std::get<1>(GetParam());
420 }
421 
TEST_P(ContentTypeTest,checkAttributes)422 TEST_P(ContentTypeTest, checkAttributes) {
423     checkAttributes();
424 }
425 
426 INSTANTIATE_TEST_CASE_P(AAudioTestAttributes, ContentTypeTest,
427         ::testing::Combine(
428                 ::testing::Values(AAUDIO_PERFORMANCE_MODE_NONE,
429                                   AAUDIO_PERFORMANCE_MODE_LOW_LATENCY),
430                 ::testing::Values(DONT_SET,
431                                   AAUDIO_UNSPECIFIED,
432                                   AAUDIO_CONTENT_TYPE_SPEECH,
433                                   AAUDIO_CONTENT_TYPE_MUSIC,
434                                   AAUDIO_CONTENT_TYPE_MOVIE,
435                                   AAUDIO_CONTENT_TYPE_SONIFICATION)),
436                 &ContentTypeTest::getTestName);
437 
438 /******************************************************************************
439  * SpatializationBehaviorTest
440  *****************************************************************************/
441 
442 using SpatializationBehaviorParam = std::tuple<aaudio_performance_mode_t,
443                                                aaudio_spatialization_behavior_t>;
444 class SpatializationBehaviorTest : public AAudioAttributesTestBase,
445                            public ::testing::WithParamInterface<SpatializationBehaviorParam> {
446 public:
getTestName(const::testing::TestParamInfo<SpatializationBehaviorParam> & info)447     static std::string getTestName(
448             const ::testing::TestParamInfo<SpatializationBehaviorParam>& info) {
449         std::stringstream ss;
450         printPerformanceModeToTestName(std::get<0>(info.param), ss);
451         ss << "_spatialization_behavior_";
452         switch (std::get<1>(info.param)) {
453             case DONT_SET:
454                 ss << "do_not_set";
455                 break;
456             case AAUDIO_UNSPECIFIED:
457                 ss << "unspecified";
458                 break;
459             case AAUDIO_SPATIALIZATION_BEHAVIOR_AUTO:
460                 ss << "auto";
461                 break;
462             case AAUDIO_SPATIALIZATION_BEHAVIOR_NEVER:
463                 ss << "never";
464                 break;
465             default:
466                 ss << "unknown";
467                 break;
468         }
469         return ss.str();
470     }
471 
472 protected:
473     void SetUp() override;
474 };
475 
SetUp()476 void SpatializationBehaviorTest::SetUp() {
477     mPerfMode = std::get<0>(GetParam());
478     mSpatializationBehavior = std::get<1>(GetParam());
479 }
480 
TEST_P(SpatializationBehaviorTest,checkAttributes)481 TEST_P(SpatializationBehaviorTest, checkAttributes) {
482     checkAttributes();
483 }
484 
485 INSTANTIATE_TEST_CASE_P(AAudioTestAttributes, SpatializationBehaviorTest,
486         ::testing::Combine(
487                 ::testing::Values(AAUDIO_PERFORMANCE_MODE_NONE,
488                                   AAUDIO_PERFORMANCE_MODE_LOW_LATENCY),
489                 ::testing::Values(DONT_SET,
490                                   AAUDIO_UNSPECIFIED,
491                                   AAUDIO_SPATIALIZATION_BEHAVIOR_AUTO,
492                                   AAUDIO_SPATIALIZATION_BEHAVIOR_NEVER)),
493                 &SpatializationBehaviorTest::getTestName);
494 
495 /******************************************************************************
496  * IsContentSpatializedTest
497  *****************************************************************************/
498 
499 using IsContentSpatializedParam = std::tuple<aaudio_performance_mode_t, int>;
500 class IsContentSpatializedTest : public AAudioAttributesTestBase,
501                                  public ::testing::WithParamInterface<IsContentSpatializedParam> {
502 public:
getTestName(const::testing::TestParamInfo<IsContentSpatializedParam> & info)503     static std::string getTestName(
504             const ::testing::TestParamInfo<IsContentSpatializedParam>& info) {
505         std::stringstream ss;
506         printPerformanceModeToTestName(std::get<0>(info.param), ss);
507         ss << "_is_content_spatialized_";
508         switch (std::get<1>(info.param)) {
509             case DONT_SET:
510                 ss << "do_not_set";
511                 break;
512             case IS_SPATIALIZED_TRUE:
513                 ss << "true";
514                 break;
515             case IS_SPATIALIZED_FALSE:
516                 ss << "false";
517                 break;
518             default:
519                 ss << "unknown";
520                 break;
521         }
522         return ss.str();
523     }
524 
525 protected:
526     void SetUp() override;
527 };
528 
SetUp()529 void IsContentSpatializedTest::SetUp() {
530     mPerfMode = std::get<0>(GetParam());
531     mIsContentSpatialized = std::get<1>(GetParam());
532 }
533 
TEST_P(IsContentSpatializedTest,checkAttributes)534 TEST_P(IsContentSpatializedTest, checkAttributes) {
535     checkAttributes();
536 }
537 
538 INSTANTIATE_TEST_CASE_P(AAudioTestAttributes, IsContentSpatializedTest,
539         ::testing::Combine(
540                 ::testing::Values(AAUDIO_PERFORMANCE_MODE_NONE,
541                                   AAUDIO_PERFORMANCE_MODE_LOW_LATENCY),
542                 ::testing::Values(DONT_SET,
543                                   IS_SPATIALIZED_TRUE,
544                                   IS_SPATIALIZED_FALSE)),
545                 &IsContentSpatializedTest::getTestName);
546 
547 /******************************************************************************
548  * InputPresetTest
549  *****************************************************************************/
550 
551 using InputPresetParam = std::tuple<aaudio_performance_mode_t, aaudio_input_preset_t>;
552 class InputPresetTest : public AAudioAttributesTestBase,
553                         public ::testing::WithParamInterface<InputPresetParam> {
554 public:
getTestName(const::testing::TestParamInfo<InputPresetParam> & info)555     static std::string getTestName(const ::testing::TestParamInfo<InputPresetParam>& info) {
556         std::stringstream ss;
557         printPerformanceModeToTestName(std::get<0>(info.param), ss);
558         ss << "_input_preset";
559         switch (std::get<1>(info.param)) {
560             case DONT_SET:
561                 ss << "do_not_set";
562                 break;
563             case AAUDIO_UNSPECIFIED:
564                 ss << "unspecified";
565                 break;
566             case AAUDIO_INPUT_PRESET_GENERIC:
567                 ss << "generic";
568                 break;
569             case AAUDIO_INPUT_PRESET_CAMCORDER:
570                 ss << "camcorder";
571                 break;
572             case AAUDIO_INPUT_PRESET_VOICE_RECOGNITION:
573                 ss << "voice_recognition";
574                 break;
575             case AAUDIO_INPUT_PRESET_VOICE_COMMUNICATION:
576                 ss << "voice_communication";
577                 break;
578             case AAUDIO_INPUT_PRESET_UNPROCESSED:
579                 ss << "unprocessed";
580                 break;
581             case AAUDIO_INPUT_PRESET_VOICE_PERFORMANCE:
582                 ss << "voice_performance";
583                 break;
584             case AAUDIO_INPUT_PRESET_SYSTEM_ECHO_REFERENCE:
585                 ss << "echo_reference_system";
586                 break;
587             case AAUDIO_INPUT_PRESET_SYSTEM_HOTWORD:
588                 ss << "hotword_system";
589                 break;
590             default:
591                 ss << "unknown";
592                 break;
593         }
594         return ss.str();
595     }
596 
597 protected:
598     void SetUp() override;
599 };
600 
SetUp()601 void InputPresetTest::SetUp() {
602     mPerfMode = std::get<0>(GetParam());
603     mPreset = std::get<1>(GetParam());
604     mDirection = AAUDIO_DIRECTION_INPUT;
605 }
606 
TEST_P(InputPresetTest,checkAttributes)607 TEST_P(InputPresetTest, checkAttributes) {
608     switch (mPreset) {
609         case AAUDIO_INPUT_PRESET_SYSTEM_ECHO_REFERENCE:
610             if (!isEchoReferenceSupported()) return;
611             enableAudioOutputPermission();
612             break;
613         case AAUDIO_INPUT_PRESET_SYSTEM_HOTWORD:
614             enableAudioHotwordPermission();
615             break;
616         default:
617             break;
618     }
619     checkAttributes();
620     disablePermissions();
621 }
622 
623 INSTANTIATE_TEST_CASE_P(AAudioTestAttributes, InputPresetTest,
624         ::testing::Combine(
625                 ::testing::Values(AAUDIO_PERFORMANCE_MODE_NONE,
626                                   AAUDIO_PERFORMANCE_MODE_LOW_LATENCY),
627                 ::testing::Values(DONT_SET,
628                                   AAUDIO_UNSPECIFIED,
629                                   AAUDIO_INPUT_PRESET_GENERIC,
630                                   AAUDIO_INPUT_PRESET_CAMCORDER,
631                                   AAUDIO_INPUT_PRESET_VOICE_RECOGNITION,
632                                   AAUDIO_INPUT_PRESET_VOICE_COMMUNICATION,
633                                   AAUDIO_INPUT_PRESET_UNPROCESSED,
634                                   AAUDIO_INPUT_PRESET_VOICE_PERFORMANCE,
635                                   AAUDIO_INPUT_PRESET_SYSTEM_ECHO_REFERENCE,
636                                   AAUDIO_INPUT_PRESET_SYSTEM_HOTWORD)),
637                 &InputPresetTest::getTestName);
638 
639 /******************************************************************************
640  * AllowCapturePolicyTest
641  *****************************************************************************/
642 
643 using AllowCapturePolicyParam = std::tuple<aaudio_performance_mode_t,
644                                            aaudio_allowed_capture_policy_t>;
645 class AllowCapturePolicyTest : public AAudioAttributesTestBase,
646                            public ::testing::WithParamInterface<AllowCapturePolicyParam> {
647 public:
getTestName(const::testing::TestParamInfo<AllowCapturePolicyParam> & info)648     static std::string getTestName(const ::testing::TestParamInfo<AllowCapturePolicyParam>& info) {
649         std::stringstream ss;
650         printPerformanceModeToTestName(std::get<0>(info.param), ss);
651         ss << "_allow_capture_policy_";
652         switch (std::get<1>(info.param)) {
653             case DONT_SET:
654                 ss << "do_not_set";
655                 break;
656             case AAUDIO_UNSPECIFIED:
657                 ss << "unspecified";
658                 break;
659             case AAUDIO_ALLOW_CAPTURE_BY_ALL:
660                 ss << "all";
661                 break;
662             case AAUDIO_ALLOW_CAPTURE_BY_SYSTEM:
663                 ss << "system";
664                 break;
665             case AAUDIO_ALLOW_CAPTURE_BY_NONE:
666                 ss << "none";
667                 break;
668             default:
669                 ss << "unknown";
670                 break;
671         }
672         return ss.str();
673     }
674 
675 protected:
676     void SetUp() override;
677 };
678 
SetUp()679 void AllowCapturePolicyTest::SetUp() {
680     mPerfMode = std::get<0>(GetParam());
681     mCapturePolicy = std::get<1>(GetParam());
682 }
683 
TEST_P(AllowCapturePolicyTest,checkAttributes)684 TEST_P(AllowCapturePolicyTest, checkAttributes) {
685     checkAttributes();
686 }
687 
688 INSTANTIATE_TEST_CASE_P(AAudioTestAttributes, AllowCapturePolicyTest,
689         ::testing::Combine(
690                 ::testing::Values(AAUDIO_PERFORMANCE_MODE_NONE,
691                                   AAUDIO_PERFORMANCE_MODE_LOW_LATENCY),
692                 ::testing::Values(DONT_SET,
693                                   AAUDIO_UNSPECIFIED,
694                                   AAUDIO_ALLOW_CAPTURE_BY_ALL,
695                                   AAUDIO_ALLOW_CAPTURE_BY_SYSTEM,
696                                   AAUDIO_ALLOW_CAPTURE_BY_NONE)),
697                 &AllowCapturePolicyTest::getTestName);
698 
699 /******************************************************************************
700  * PrivacyModeTest
701  *****************************************************************************/
702 
703 using PrivacyModeParam = std::tuple<aaudio_performance_mode_t, int>;
704 class PrivacyModeTest : public AAudioAttributesTestBase,
705                         public ::testing::WithParamInterface<PrivacyModeParam> {
706 public:
getTestName(const::testing::TestParamInfo<PrivacyModeParam> & info)707     static std::string getTestName(const ::testing::TestParamInfo<PrivacyModeParam>& info) {
708         std::stringstream ss;
709         printPerformanceModeToTestName(std::get<0>(info.param), ss);
710         ss << "_privacy_mode_";
711         switch (std::get<1>(info.param)) {
712             case DONT_SET:
713                 ss << "do_not_set";
714                 break;
715             case IS_PRIVACY_SENSITIVE_TRUE:
716                 ss << "true";
717                 break;
718             case IS_PRIVACY_SENSITIVE_FALSE:
719                 ss << "false";
720                 break;
721             default:
722                 ss << "unknown";
723                 break;
724         }
725         return ss.str();
726     }
727 
728 protected:
729     void SetUp() override;
730 };
731 
SetUp()732 void PrivacyModeTest::SetUp() {
733     mPerfMode = std::get<0>(GetParam());
734     mIsPrivacySensitive = std::get<1>(GetParam());
735     mDirection = AAUDIO_DIRECTION_INPUT;
736 }
737 
TEST_P(PrivacyModeTest,checkAttributes)738 TEST_P(PrivacyModeTest, checkAttributes) {
739     checkAttributes();
740 }
741 
742 INSTANTIATE_TEST_CASE_P(AAudioTestAttributes, PrivacyModeTest,
743         ::testing::Combine(
744                 ::testing::Values(AAUDIO_PERFORMANCE_MODE_NONE,
745                                   AAUDIO_PERFORMANCE_MODE_LOW_LATENCY),
746                 ::testing::Values(DONT_SET,
747                                   IS_PRIVACY_SENSITIVE_TRUE,
748                                   IS_PRIVACY_SENSITIVE_FALSE)),
749                 &PrivacyModeTest::getTestName);
750 
751 /******************************************************************************
752  * SystemUsageTest
753  *****************************************************************************/
754 
755 using SystemUsageParam = std::tuple<aaudio_performance_mode_t, aaudio_usage_t>;
756 class SystemUsageTest : public AAudioCtsBase,
757                         public ::testing::WithParamInterface<SystemUsageParam> {
758 public:
getTestName(const::testing::TestParamInfo<SystemUsageParam> & info)759     static std::string getTestName(const ::testing::TestParamInfo<SystemUsageParam>& info) {
760         std::stringstream ss;
761         printPerformanceModeToTestName(std::get<0>(info.param), ss);
762         ss << "_system_usage_";
763         switch (std::get<1>(info.param)) {
764             case AAUDIO_SYSTEM_USAGE_EMERGENCY:
765                 ss << "emergency";
766                 break;
767             case AAUDIO_SYSTEM_USAGE_SAFETY:
768                 ss << "safety";
769                 break;
770             case AAUDIO_SYSTEM_USAGE_VEHICLE_STATUS:
771                 ss << "vehicle_status";
772                 break;
773             case AAUDIO_SYSTEM_USAGE_ANNOUNCEMENT:
774                 ss << "announcement";
775                 break;
776             default:
777                 break;
778         }
779         return ss.str();
780     }
781 };
782 
TEST_P(SystemUsageTest,rejected)783 TEST_P(SystemUsageTest, rejected) {
784     const auto param = GetParam();
785     AAudioStreamBuilder *aaudioBuilder = nullptr;
786     AAudioStream *aaudioStream = nullptr;
787 
788     // Use an AAudioStreamBuilder to contain requested parameters.
789     ASSERT_EQ(AAUDIO_OK, AAudio_createStreamBuilder(&aaudioBuilder));
790 
791     AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, std::get<0>(param));
792     AAudioStreamBuilder_setUsage(aaudioBuilder, std::get<1>(param));
793 
794     aaudio_result_t result = AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream);
795 
796     // Get failed status when trying to create an AAudioStream using the Builder. There are two
797     // potential failures: one if the device doesn't support the system usage, and the  other
798     // if it does but this test doesn't have the MODIFY_AUDIO_ROUTING permission required to
799     // use it.
800     ASSERT_TRUE(result == AAUDIO_ERROR_ILLEGAL_ARGUMENT
801             || result == AAUDIO_ERROR_INTERNAL);
802     AAudioStreamBuilder_delete(aaudioBuilder);
803 }
804 
805 INSTANTIATE_TEST_CASE_P(AAudioTestAttributes, SystemUsageTest,
806         ::testing::Combine(
807                 ::testing::Values(AAUDIO_PERFORMANCE_MODE_NONE,
808                                   AAUDIO_PERFORMANCE_MODE_LOW_LATENCY),
809                 ::testing::Values(AAUDIO_SYSTEM_USAGE_EMERGENCY,
810                                   AAUDIO_SYSTEM_USAGE_SAFETY,
811                                   AAUDIO_SYSTEM_USAGE_VEHICLE_STATUS,
812                                   AAUDIO_SYSTEM_USAGE_ANNOUNCEMENT)),
813                 &SystemUsageTest::getTestName);
814 
815 /******************************************************************************
816  * PermissionGatedInputPresetTest
817  *****************************************************************************/
818 
819 using PermissionGatedInputPresetParam = std::tuple<aaudio_performance_mode_t,
820                                                    aaudio_input_preset_t>;
821 class PermissionGatedInputPresetTest : public AAudioCtsBase,
822                         public ::testing::WithParamInterface<PermissionGatedInputPresetParam> {
823 public:
getTestName(const::testing::TestParamInfo<PermissionGatedInputPresetParam> & info)824     static std::string getTestName(
825             const ::testing::TestParamInfo<PermissionGatedInputPresetParam>& info) {
826         std::stringstream ss;
827         printPerformanceModeToTestName(std::get<0>(info.param), ss);
828         ss << "_input_preset_";
829         switch (std::get<1>(info.param)) {
830             case AAUDIO_INPUT_PRESET_SYSTEM_ECHO_REFERENCE:
831                 ss << "echo_reference_system";
832                 break;
833             case AAUDIO_INPUT_PRESET_SYSTEM_HOTWORD:
834                 ss << "hotword_system";
835                 break;
836             default:
837                 break;
838         }
839         return ss.str();
840     }
841 };
842 
TEST_P(PermissionGatedInputPresetTest,openStreamFails)843 TEST_P(PermissionGatedInputPresetTest, openStreamFails) {
844     if (!deviceSupportsFeature(FEATURE_RECORDING)) return;
845 
846     disablePermissions();
847 
848     std::unique_ptr<float[]> buffer(new float[kNumFrames * kChannelCount]);
849 
850     const auto param = GetParam();
851     AAudioStreamBuilder *aaudioBuilder = nullptr;
852     AAudioStream *aaudioStream = nullptr;
853 
854     // Use an AAudioStreamBuilder to contain requested parameters.
855     ASSERT_EQ(AAUDIO_OK, AAudio_createStreamBuilder(&aaudioBuilder));
856 
857     AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, std::get<0>(param));
858     AAudioStreamBuilder_setInputPreset(aaudioBuilder, std::get<1>(param));
859     AAudioStreamBuilder_setDirection(aaudioBuilder, AAUDIO_DIRECTION_INPUT);
860 
861     aaudio_result_t result = AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream);
862 
863     // openStream should not return AAUDIO_OK. If it does, close the stream.
864     if (result == AAUDIO_OK) {
865         AAudioStream_close(aaudioStream);
866     }
867     AAudioStreamBuilder_delete(aaudioBuilder);
868 
869     // The test should not have the correct permission required to use the preset.
870     ASSERT_NE(result, AAUDIO_OK);
871 }
872 
873 INSTANTIATE_TEST_CASE_P(AAudioTestAttributes, PermissionGatedInputPresetTest,
874                         ::testing::Combine(
875                                 ::testing::Values(AAUDIO_PERFORMANCE_MODE_NONE,
876                                                   AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
877                                                   AAUDIO_PERFORMANCE_MODE_POWER_SAVING),
878                                 ::testing::Values(AAUDIO_INPUT_PRESET_SYSTEM_ECHO_REFERENCE,
879                                                   AAUDIO_INPUT_PRESET_SYSTEM_HOTWORD)),
880                         &PermissionGatedInputPresetTest::getTestName);
881