• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 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 #define LOG_NDEBUG 0
18 #define LOG_TAG "AAudioTest"
19 
20 #include <cstring>
21 #include <sstream>
22 #include <utility>
23 
24 #include <aaudio/AAudio.h>
25 #include <android/log.h>
26 #include <android-base/properties.h>
27 #include <gtest/gtest.h>
28 #include <system/audio.h> /* FCC_LIMIT */
29 
30 #include "utils.h"
31 
32 /**
33  * See https://source.android.com/devices/tech/perf/low-ram
34  * for more details.
35  *
36  * @return true if running on low memory device
37  */
isLowRamDevice()38 static bool isLowRamDevice() {
39     return android::base::GetBoolProperty("ro.config.low_ram", false);
40 }
41 
42 // Creates a builder, the caller takes ownership
create_stream_builder(AAudioStreamBuilder ** aaudioBuilder)43 static void create_stream_builder(AAudioStreamBuilder** aaudioBuilder) {
44     aaudio_result_t result = AAudio_createStreamBuilder(aaudioBuilder);
45     ASSERT_EQ(AAUDIO_OK, result);
46     ASSERT_NE(nullptr, *aaudioBuilder);
47 }
48 
49 enum class Expect { FAIL, SUCCEED, NOT_CRASH };
50 
51 // Tries to open an audio stream using a primed Builder.
52 // Takes ownership of the Builder.
try_opening_audio_stream(AAudioStreamBuilder * aaudioBuilder,Expect expect)53 static void try_opening_audio_stream(AAudioStreamBuilder *aaudioBuilder, Expect expect) {
54     // Create an AAudioStream using the Builder.
55     AAudioStream *aaudioStream = nullptr;
56     int64_t beforeTimeNanos = getNanoseconds();
57     aaudio_result_t result = AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream);
58     if (expect == Expect::FAIL) {
59         ASSERT_NE(AAUDIO_OK, result);
60         ASSERT_EQ(nullptr, aaudioStream);
61     } else if (expect == Expect::SUCCEED) {
62         ASSERT_EQ(AAUDIO_OK, result);
63         ASSERT_NE(nullptr, aaudioStream);
64     } else { // NOT_CRASH
65         ASSERT_TRUE(((result < 0) && (aaudioStream == nullptr))
66                 || ((result == AAUDIO_OK) && (aaudioStream != nullptr)));
67     }
68 
69     // The stream should be open within one second.
70     static const int64_t kNanosPerSecond = 1e9;
71     ASSERT_LT(getNanoseconds() - beforeTimeNanos, kNanosPerSecond)
72             << "It took more than one second to open stream";
73 
74     // Cleanup
75     ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_delete(aaudioBuilder));
76     if (aaudioStream != nullptr) {
77         beforeTimeNanos = getNanoseconds();
78         ASSERT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream));
79         // The stream should be closed within one second.
80         ASSERT_LT(getNanoseconds() - beforeTimeNanos, kNanosPerSecond)
81                 << "It took more than one second to close stream";
82     }
83 }
84 
85 // Test creating a default stream with specific devices
runtest_aaudio_devices(int32_t deviceId,Expect expect)86 static void runtest_aaudio_devices(int32_t deviceId, Expect expect) {
87     AAudioStreamBuilder *aaudioBuilder = nullptr;
88     create_stream_builder(&aaudioBuilder);
89     AAudioStreamBuilder_setDeviceId(aaudioBuilder, deviceId);
90     try_opening_audio_stream(aaudioBuilder, expect);
91 }
92 
93 class AAudioTest : public AAudioCtsBase {};
94 
TEST_F(AAudioTest,aaudio_stream_device_unspecified)95 TEST_F(AAudioTest, aaudio_stream_device_unspecified) {
96     runtest_aaudio_devices(AAUDIO_UNSPECIFIED, Expect::NOT_CRASH);
97 }
98 
99 /* FIXME - why can we open this device? What is an illegal deviceId?
100 TEST_F(AAudioTest, aaudio_stream_device_absurd) {
101     runtest_aaudio_devices(19736459, true);
102 }
103 */
104 /* FIXME review
105 TEST_F(AAudioTest, aaudio_stream_device_reasonable) {
106     runtest_aaudio_devices(1, false);
107 }
108 */
109 
110 /* FIXME - why can we open this device? What is an illegal deviceId?
111 TEST_F(AAudioTest, aaudio_stream_device_negative) {
112     runtest_aaudio_devices(-765, true);
113 }
114 */
115 
116 // Test creating a default stream with everything unspecified.
TEST_F(AAudioTest,aaudio_stream_unspecified)117 TEST_F(AAudioTest, aaudio_stream_unspecified) {
118     if (!deviceSupportsFeature(FEATURE_PLAYBACK)) return;
119     AAudioStreamBuilder *aaudioBuilder = nullptr;
120     create_stream_builder(&aaudioBuilder);
121 
122     // Create an AAudioStream using the Builder.
123     AAudioStream *aaudioStream = nullptr;
124     ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream));
125     ASSERT_NE(nullptr, aaudioStream);
126 
127     // Cleanup
128     EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_delete(aaudioBuilder));
129     EXPECT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream));
130 }
131 
132 class AAudioStreamBuilderSamplingRateTest : public AAudioCtsBase,
133                                             public ::testing::WithParamInterface<int32_t> {
134   public:
getTestName(const::testing::TestParamInfo<int32_t> & info)135     static std::string getTestName(const ::testing::TestParamInfo<int32_t>& info) {
136         return info.param >= 0 ? std::to_string(info.param) : "_" + std::to_string(-info.param);
137     }
138   protected:
isValidSamplingRate(int32_t sr)139     static bool isValidSamplingRate(int32_t sr) {
140         return sr == AAUDIO_UNSPECIFIED || (sr >= 8000 && sr <= 1000000);
141     }
142 };
143 
TEST_P(AAudioStreamBuilderSamplingRateTest,openStream)144 TEST_P(AAudioStreamBuilderSamplingRateTest, openStream) {
145     if (!deviceSupportsFeature(FEATURE_PLAYBACK)) return;
146     const int32_t sampleRate = GetParam();
147     const bool isSampleRateValid = isValidSamplingRate(sampleRate);
148     // Opening a stream with a high sample rates can fail because the required buffer size
149     // is bigger than the heap size. This is a limitation in AudioFlinger.  b/112528380
150     if (isSampleRateValid && isLowRamDevice() && (sampleRate > 192000)) {
151         return; // skip this test
152     }
153     AAudioStreamBuilder *aaudioBuilder = nullptr;
154     create_stream_builder(&aaudioBuilder);
155     AAudioStreamBuilder_setSampleRate(aaudioBuilder, sampleRate);
156     try_opening_audio_stream(
157             aaudioBuilder, isSampleRateValid ? Expect::SUCCEED : Expect::FAIL);
158 }
159 
160 INSTANTIATE_TEST_CASE_P(SR, AAudioStreamBuilderSamplingRateTest,
161         ::testing::Values(
162                 // Commonly used values
163                 AAUDIO_UNSPECIFIED, 8000, 11025, 16000, 22050, 44100, 48000, 88200, 96000,
164                 176400, 192000, 384000,
165                 // Odd values
166                 AAUDIO_UNSPECIFIED - 1, AAUDIO_UNSPECIFIED + 1, 1234, 10000000),
167         &AAudioStreamBuilderSamplingRateTest::getTestName);
168 
169 class AAudioStreamBuilderChannelCountTest : public AAudioCtsBase,
170                                             public ::testing::WithParamInterface<int32_t> {
171   public:
getTestName(const::testing::TestParamInfo<int32_t> & info)172     static std::string getTestName(const ::testing::TestParamInfo<int32_t>& info) {
173         return info.param >= 0 ? std::to_string(info.param) : "_" + std::to_string(-info.param);
174     }
175   protected:
isValidChannelCount(int32_t cc)176     static bool isValidChannelCount(int32_t cc) {
177         return cc == AAUDIO_UNSPECIFIED || (cc >= 1 && cc <= FCC_LIMIT);
178     }
179 };
180 
TEST_P(AAudioStreamBuilderChannelCountTest,openStream)181 TEST_P(AAudioStreamBuilderChannelCountTest, openStream) {
182     if (!deviceSupportsFeature(FEATURE_PLAYBACK)) return;
183     AAudioStreamBuilder *aaudioBuilder = nullptr;
184     create_stream_builder(&aaudioBuilder);
185     AAudioStreamBuilder_setChannelCount(aaudioBuilder, GetParam());
186     try_opening_audio_stream(
187             aaudioBuilder, isValidChannelCount(GetParam()) ? Expect::SUCCEED : Expect::FAIL);
188 }
189 
190 INSTANTIATE_TEST_CASE_P(CC, AAudioStreamBuilderChannelCountTest,
191         ::testing::Values(
192                 // Reasonable values that should work OK.
193                 AAUDIO_UNSPECIFIED, 1, 2, 3, 4, 5, 6, 7, 8, FCC_LIMIT,
194                 // These values should fail.
195                 AAUDIO_UNSPECIFIED - 1, (FCC_LIMIT + 1), 1000, 1000000),
196         &AAudioStreamBuilderChannelCountTest::getTestName);
197 
198 class AAudioStreamBuilderFormatTest : public AAudioCtsBase,
199                                       public ::testing::WithParamInterface<aaudio_format_t> {
200   public:
getTestName(const::testing::TestParamInfo<aaudio_format_t> & info)201     static std::string getTestName(const ::testing::TestParamInfo<aaudio_format_t>& info) {
202         return info.param >= 0 ? std::to_string(info.param) : "_" + std::to_string(-info.param);
203     }
204   protected:
isValidFormat(aaudio_format_t f)205     static bool isValidFormat(aaudio_format_t f) {
206         switch (f) {
207             case AAUDIO_FORMAT_UNSPECIFIED:
208             case AAUDIO_FORMAT_PCM_I16:
209             case AAUDIO_FORMAT_PCM_FLOAT:
210             case AAUDIO_FORMAT_IEC61937:
211             case AAUDIO_FORMAT_PCM_I24_PACKED:
212             case AAUDIO_FORMAT_PCM_I32:
213                 return true;
214         }
215         return false;
216     }
217 };
218 
TEST_P(AAudioStreamBuilderFormatTest,openStream)219 TEST_P(AAudioStreamBuilderFormatTest, openStream) {
220     if (!deviceSupportsFeature(FEATURE_PLAYBACK)) return;
221     AAudioStreamBuilder *aaudioBuilder = nullptr;
222     create_stream_builder(&aaudioBuilder);
223     AAudioStreamBuilder_setFormat(aaudioBuilder, GetParam());
224     const aaudio_format_t format = GetParam();
225     Expect expectedResult = isValidFormat(format) ? Expect::SUCCEED : Expect::FAIL;
226     if (format == AAUDIO_FORMAT_IEC61937) {
227         expectedResult = isIEC61937Supported() ? Expect::SUCCEED : Expect::FAIL;
228         // For IEC61937, sample rate and channel mask should be specified.
229         AAudioStreamBuilder_setSampleRate(aaudioBuilder, 48000);
230         AAudioStreamBuilder_setChannelMask(aaudioBuilder, AAUDIO_CHANNEL_STEREO);
231     }
232     try_opening_audio_stream(aaudioBuilder, expectedResult);
233 }
234 
235 INSTANTIATE_TEST_CASE_P(F, AAudioStreamBuilderFormatTest,
236         ::testing::Values(
237                 // Reasonable values
238                 AAUDIO_FORMAT_UNSPECIFIED, AAUDIO_FORMAT_PCM_I16, AAUDIO_FORMAT_PCM_FLOAT,
239                 AAUDIO_FORMAT_PCM_I24_PACKED, AAUDIO_FORMAT_PCM_I32, AAUDIO_FORMAT_IEC61937,
240                 // Odd values
241                 AAUDIO_FORMAT_INVALID, AAUDIO_FORMAT_INVALID - 1, 100, 1000000, 10000000),
242         &AAudioStreamBuilderFormatTest::getTestName);
243 
244 class AAudioStreamBuilderSharingModeTest :
245         public AAudioCtsBase, public ::testing::WithParamInterface<aaudio_sharing_mode_t> {
246   public:
getTestName(const::testing::TestParamInfo<aaudio_sharing_mode_t> & info)247     static std::string getTestName(const ::testing::TestParamInfo<aaudio_sharing_mode_t>& info) {
248         return info.param >= 0 ? std::to_string(info.param) : "_" + std::to_string(-info.param);
249     }
250   protected:
isValidSharingMode(aaudio_sharing_mode_t f)251     static bool isValidSharingMode(aaudio_sharing_mode_t f) {
252         return f == AAUDIO_SHARING_MODE_SHARED || f == AAUDIO_SHARING_MODE_EXCLUSIVE;
253     }
254 };
255 
TEST_P(AAudioStreamBuilderSharingModeTest,openStream)256 TEST_P(AAudioStreamBuilderSharingModeTest, openStream) {
257     if (!deviceSupportsFeature(FEATURE_PLAYBACK)) return;
258     AAudioStreamBuilder *aaudioBuilder = nullptr;
259     create_stream_builder(&aaudioBuilder);
260     AAudioStreamBuilder_setSharingMode(aaudioBuilder, GetParam());
261     try_opening_audio_stream(
262             aaudioBuilder, isValidSharingMode(GetParam()) ? Expect::SUCCEED : Expect::FAIL);
263 }
264 
265 INSTANTIATE_TEST_CASE_P(SM, AAudioStreamBuilderSharingModeTest,
266         ::testing::Values(
267                 // Reasonable values
268                 AAUDIO_SHARING_MODE_SHARED, AAUDIO_SHARING_MODE_EXCLUSIVE,
269                 // Odd values
270                 -1, 100, 1000000, 10000000),
271         &AAudioStreamBuilderSharingModeTest::getTestName);
272 
273 class AAudioStreamBuilderDirectionTest : public AAudioCtsBase,
274                                          public ::testing::WithParamInterface<aaudio_direction_t> {
275   public:
getTestName(const::testing::TestParamInfo<aaudio_direction_t> & info)276     static std::string getTestName(const ::testing::TestParamInfo<aaudio_direction_t>& info) {
277         return info.param >= 0 ? std::to_string(info.param) : "_" + std::to_string(-info.param);
278     }
279   protected:
isValidDirection(aaudio_direction_t f)280     static bool isValidDirection(aaudio_direction_t f) {
281         return f == AAUDIO_DIRECTION_OUTPUT || f == AAUDIO_DIRECTION_INPUT;
282     }
283 };
284 
TEST_P(AAudioStreamBuilderDirectionTest,openStream)285 TEST_P(AAudioStreamBuilderDirectionTest, openStream) {
286     if (GetParam() == AAUDIO_DIRECTION_OUTPUT
287             && !deviceSupportsFeature(FEATURE_PLAYBACK)) return;
288     if (GetParam() == AAUDIO_DIRECTION_INPUT
289             && !deviceSupportsFeature(FEATURE_RECORDING)) return;
290     AAudioStreamBuilder *aaudioBuilder = nullptr;
291     create_stream_builder(&aaudioBuilder);
292     AAudioStreamBuilder_setDirection(aaudioBuilder, GetParam());
293     try_opening_audio_stream(
294             aaudioBuilder, isValidDirection(GetParam()) ? Expect::SUCCEED : Expect::FAIL);
295 }
296 
297 INSTANTIATE_TEST_CASE_P(SD, AAudioStreamBuilderDirectionTest,
298         ::testing::Values(
299                 // Reasonable values
300                 AAUDIO_DIRECTION_OUTPUT, AAUDIO_DIRECTION_INPUT,
301                 // Odd values
302                 -1, 100, 1000000, 10000000),
303         &AAudioStreamBuilderDirectionTest::getTestName);
304 
305 class AAudioStreamBuilderBufferCapacityTest : public AAudioCtsBase,
306                                               public ::testing::WithParamInterface<int32_t> {
307   public:
getTestName(const::testing::TestParamInfo<int32_t> & info)308     static std::string getTestName(const ::testing::TestParamInfo<int32_t>& info) {
309         return info.param >= 0 ? std::to_string(info.param) : "_" + std::to_string(-info.param);
310     }
311   protected:
312     // There is no hard defined limit, the actual maximum capacity depends
313     // on the implementation.
isValidCapacity(int32_t bc)314     static bool isValidCapacity(int32_t bc) {
315         return bc == AAUDIO_UNSPECIFIED || bc >= 0;
316     }
317 };
318 
TEST_P(AAudioStreamBuilderBufferCapacityTest,openStream)319 TEST_P(AAudioStreamBuilderBufferCapacityTest, openStream) {
320     if (!deviceSupportsFeature(FEATURE_PLAYBACK)) return;
321     AAudioStreamBuilder *aaudioBuilder = nullptr;
322     create_stream_builder(&aaudioBuilder);
323     AAudioStreamBuilder_setBufferCapacityInFrames(aaudioBuilder, GetParam());
324     try_opening_audio_stream(
325             aaudioBuilder, isValidCapacity(GetParam()) ? Expect::SUCCEED : Expect::FAIL);
326 }
327 
328 INSTANTIATE_TEST_CASE_P(BC, AAudioStreamBuilderBufferCapacityTest,
329         ::testing::Values(
330                 // Reasonable values that should not fail
331                 AAUDIO_UNSPECIFIED, 8 * 192, 2 * 1024,
332                 // Odd values
333                 AAUDIO_UNSPECIFIED - 1),
334         &AAudioStreamBuilderBufferCapacityTest::getTestName);
335 
336 class AAudioStreamBuilderPerfModeTest :
337         public AAudioCtsBase, public ::testing::WithParamInterface<aaudio_performance_mode_t> {
338   public:
getTestName(const::testing::TestParamInfo<aaudio_performance_mode_t> & info)339     static std::string getTestName(const ::testing::TestParamInfo<aaudio_performance_mode_t>& info) {
340         return info.param >= 0 ? std::to_string(info.param) : "_" + std::to_string(-info.param);
341     }
342   protected:
isValidPerfMode(aaudio_performance_mode_t pm)343     static bool isValidPerfMode(aaudio_performance_mode_t pm) {
344         switch (pm) {
345             case AAUDIO_PERFORMANCE_MODE_NONE:
346             case AAUDIO_PERFORMANCE_MODE_POWER_SAVING:
347             case AAUDIO_PERFORMANCE_MODE_LOW_LATENCY:
348                 return true;
349         }
350         return false;
351     }
352 };
353 
TEST_P(AAudioStreamBuilderPerfModeTest,openStream)354 TEST_P(AAudioStreamBuilderPerfModeTest, openStream) {
355     if (!deviceSupportsFeature(FEATURE_PLAYBACK)) return;
356     AAudioStreamBuilder *aaudioBuilder = nullptr;
357     create_stream_builder(&aaudioBuilder);
358     AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, GetParam());
359     try_opening_audio_stream(
360             aaudioBuilder, isValidPerfMode(GetParam()) ? Expect::SUCCEED : Expect::FAIL);
361 }
362 
363 INSTANTIATE_TEST_CASE_P(PM, AAudioStreamBuilderPerfModeTest,
364         ::testing::Values(
365                 // Reasonable values
366                 AAUDIO_PERFORMANCE_MODE_NONE,
367                 AAUDIO_PERFORMANCE_MODE_POWER_SAVING,
368                 AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
369                 // Odd values
370                 AAUDIO_UNSPECIFIED - 1, AAUDIO_UNSPECIFIED, 100, 1000000, 10000000),
371         &AAudioStreamBuilderPerfModeTest::getTestName);
372 
373 class AAudioStreamBuilderChannelMaskTest :
374         public AAudioCtsBase, public ::testing::WithParamInterface<aaudio_channel_mask_t> {
375 public:
getTestName(const::testing::TestParamInfo<aaudio_channel_mask_t> & info)376     static std::string getTestName(const ::testing::TestParamInfo<aaudio_channel_mask_t>& info) {
377         std::stringstream ss;
378         ss << "0x" << std::hex << info.param;
379         return ss.str();
380     }
381 protected:
382 
isValidChannelMask(aaudio_channel_mask_t channelMask,bool isInput)383     static bool isValidChannelMask(aaudio_channel_mask_t channelMask, bool isInput) {
384         if (channelMask == AAUDIO_UNSPECIFIED) {
385             return true;
386         }
387 
388         if (__builtin_popcount(channelMask) > FCC_LIMIT) {
389             return false;
390         }
391 
392         if (isInput) {
393             switch (channelMask) {
394                 case AAUDIO_CHANNEL_MONO:
395                 case AAUDIO_CHANNEL_STEREO:
396                 case AAUDIO_CHANNEL_FRONT_BACK:
397                 case AAUDIO_CHANNEL_2POINT0POINT2:
398                 case AAUDIO_CHANNEL_2POINT1POINT2:
399                 case AAUDIO_CHANNEL_3POINT0POINT2:
400                 case AAUDIO_CHANNEL_3POINT1POINT2:
401                 case AAUDIO_CHANNEL_5POINT1:
402                     return true;
403             }
404             return false;
405         } else {
406             switch (channelMask) {
407                 case AAUDIO_CHANNEL_MONO:
408                 case AAUDIO_CHANNEL_STEREO:
409                 case AAUDIO_CHANNEL_2POINT1:
410                 case AAUDIO_CHANNEL_TRI:
411                 case AAUDIO_CHANNEL_TRI_BACK:
412                 case AAUDIO_CHANNEL_3POINT1:
413                 case AAUDIO_CHANNEL_2POINT0POINT2:
414                 case AAUDIO_CHANNEL_2POINT1POINT2:
415                 case AAUDIO_CHANNEL_3POINT0POINT2:
416                 case AAUDIO_CHANNEL_3POINT1POINT2:
417                 case AAUDIO_CHANNEL_QUAD:
418                 case AAUDIO_CHANNEL_QUAD_SIDE:
419                 case AAUDIO_CHANNEL_SURROUND:
420                 case AAUDIO_CHANNEL_PENTA:
421                 case AAUDIO_CHANNEL_5POINT1:
422                 case AAUDIO_CHANNEL_5POINT1_SIDE:
423                 case AAUDIO_CHANNEL_5POINT1POINT2:
424                 case AAUDIO_CHANNEL_5POINT1POINT4:
425                 case AAUDIO_CHANNEL_6POINT1:
426                 case AAUDIO_CHANNEL_7POINT1:
427                 case AAUDIO_CHANNEL_7POINT1POINT2:
428                 case AAUDIO_CHANNEL_7POINT1POINT4:
429                 case AAUDIO_CHANNEL_9POINT1POINT4:
430                 case AAUDIO_CHANNEL_9POINT1POINT6:
431                     return true;
432             }
433             return false;
434         }
435     }
436 
437     void testChannelMask(aaudio_channel_mask_t channelMask, aaudio_direction_t direction);
438 };
439 
testChannelMask(aaudio_channel_mask_t channelMask,aaudio_direction_t direction)440 void AAudioStreamBuilderChannelMaskTest::testChannelMask(aaudio_channel_mask_t channelMask,
441                                                          aaudio_direction_t direction) {
442     AAudioStreamBuilder *aaudioBuilder = nullptr;
443     create_stream_builder(&aaudioBuilder);
444     AAudioStreamBuilder_setDirection(aaudioBuilder, direction);
445     AAudioStreamBuilder_setChannelMask(aaudioBuilder, channelMask);
446     const Expect expect =
447             isValidChannelMask(channelMask, direction) ? Expect::SUCCEED : Expect::FAIL;
448     AAudioStream *aaudioStream = nullptr;
449     aaudio_result_t result = AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream);
450     if (expect == Expect::FAIL) {
451         ASSERT_NE(AAUDIO_OK, result);
452         ASSERT_EQ(nullptr, aaudioStream);
453     } else if (expect == Expect::SUCCEED) {
454         ASSERT_EQ(AAUDIO_OK, result);
455         ASSERT_NE(nullptr, aaudioStream);
456         ASSERT_NE(0, AAudioStream_getChannelCount(aaudioStream));
457         ASSERT_NE(0, AAudioStream_getHardwareChannelCount(aaudioStream));
458         ASSERT_NE(AAUDIO_UNSPECIFIED, AAudioStream_getChannelMask(aaudioStream));
459         ASSERT_NE(AAUDIO_CHANNEL_INVALID, AAudioStream_getChannelMask(aaudioStream));
460     } else { // NOT_CRASH
461         ASSERT_TRUE(((result < 0) && (aaudioStream == nullptr))
462                 || ((result == AAUDIO_OK) && (aaudioStream != nullptr)));
463     }
464 
465     // Cleanup
466     ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_delete(aaudioBuilder));
467     if (aaudioStream != nullptr) {
468         ASSERT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream));
469     }
470 }
471 
TEST_P(AAudioStreamBuilderChannelMaskTest,openInputStream)472 TEST_P(AAudioStreamBuilderChannelMaskTest, openInputStream) {
473     if (!deviceSupportsFeature(FEATURE_RECORDING)) {
474         return;
475     }
476     testChannelMask(GetParam(), AAUDIO_DIRECTION_INPUT);
477 }
478 
TEST_P(AAudioStreamBuilderChannelMaskTest,openOutputStream)479 TEST_P(AAudioStreamBuilderChannelMaskTest, openOutputStream) {
480     if (!deviceSupportsFeature(FEATURE_PLAYBACK)) {
481         return;
482     }
483     testChannelMask(GetParam(), AAUDIO_DIRECTION_OUTPUT);
484 }
485 
486 INSTANTIATE_TEST_CASE_P(
487         CM, AAudioStreamBuilderChannelMaskTest,
488         ::testing::Values(
489                 // UNSPECIFIED is valid channel mask
490                 AAUDIO_UNSPECIFIED,
491                 AAUDIO_CHANNEL_INVALID,
492                 // Channel mask listed in audio.h
493                 // AAUDIO_CHANNEL_FRONT_LEFT,
494                 AAUDIO_CHANNEL_FRONT_RIGHT,
495                 AAUDIO_CHANNEL_FRONT_CENTER,
496                 AAUDIO_CHANNEL_LOW_FREQUENCY,
497                 AAUDIO_CHANNEL_BACK_LEFT,
498                 AAUDIO_CHANNEL_BACK_RIGHT,
499                 AAUDIO_CHANNEL_FRONT_LEFT_OF_CENTER,
500                 AAUDIO_CHANNEL_FRONT_RIGHT_OF_CENTER,
501                 AAUDIO_CHANNEL_BACK_CENTER,
502                 AAUDIO_CHANNEL_SIDE_LEFT,
503                 AAUDIO_CHANNEL_SIDE_RIGHT,
504                 AAUDIO_CHANNEL_TOP_CENTER,
505                 AAUDIO_CHANNEL_TOP_FRONT_LEFT,
506                 AAUDIO_CHANNEL_TOP_FRONT_CENTER,
507                 AAUDIO_CHANNEL_TOP_FRONT_RIGHT,
508                 AAUDIO_CHANNEL_TOP_BACK_LEFT,
509                 AAUDIO_CHANNEL_TOP_BACK_CENTER,
510                 AAUDIO_CHANNEL_TOP_BACK_RIGHT,
511                 AAUDIO_CHANNEL_TOP_SIDE_LEFT,
512                 AAUDIO_CHANNEL_TOP_SIDE_RIGHT,
513                 AAUDIO_CHANNEL_BOTTOM_FRONT_LEFT,
514                 AAUDIO_CHANNEL_BOTTOM_FRONT_CENTER,
515                 AAUDIO_CHANNEL_BOTTOM_FRONT_RIGHT,
516                 AAUDIO_CHANNEL_LOW_FREQUENCY_2,
517                 AAUDIO_CHANNEL_FRONT_WIDE_LEFT,
518                 AAUDIO_CHANNEL_FRONT_WIDE_RIGHT,
519                 AAUDIO_CHANNEL_MONO,
520                 AAUDIO_CHANNEL_STEREO,
521                 AAUDIO_CHANNEL_2POINT1,
522                 AAUDIO_CHANNEL_TRI,
523                 AAUDIO_CHANNEL_TRI_BACK,
524                 AAUDIO_CHANNEL_3POINT1,
525                 AAUDIO_CHANNEL_2POINT0POINT2,
526                 AAUDIO_CHANNEL_2POINT1POINT2,
527                 AAUDIO_CHANNEL_3POINT0POINT2,
528                 AAUDIO_CHANNEL_3POINT1POINT2,
529                 AAUDIO_CHANNEL_QUAD,
530                 AAUDIO_CHANNEL_QUAD_SIDE,
531                 AAUDIO_CHANNEL_SURROUND,
532                 AAUDIO_CHANNEL_PENTA,
533                 AAUDIO_CHANNEL_5POINT1,
534                 AAUDIO_CHANNEL_5POINT1_SIDE,
535                 AAUDIO_CHANNEL_6POINT1,
536                 AAUDIO_CHANNEL_7POINT1,
537                 AAUDIO_CHANNEL_5POINT1POINT2,
538                 AAUDIO_CHANNEL_5POINT1POINT4,
539                 AAUDIO_CHANNEL_7POINT1POINT2,
540                 AAUDIO_CHANNEL_7POINT1POINT4,
541                 AAUDIO_CHANNEL_9POINT1POINT4,
542                 AAUDIO_CHANNEL_9POINT1POINT6,
543                 AAUDIO_CHANNEL_FRONT_BACK,
544                 // Odd value
545                 0x20000000,
546                 0x30000000,
547                 0x40000005),
548         &AAudioStreamBuilderChannelMaskTest::getTestName);
549 
550 using ChannelMaskAndCountParams = std::pair<aaudio_direction_t, aaudio_channel_mask_t>;
551 class AAudioStreamBuilderChannelMaskAndCountTest :
552         public AAudioCtsBase, public ::testing::WithParamInterface<ChannelMaskAndCountParams> {
553 public:
getTestName(const::testing::TestParamInfo<ChannelMaskAndCountParams> & info)554     static std::string getTestName(
555             const ::testing::TestParamInfo<ChannelMaskAndCountParams>& info) {
556         std::stringstream ss;
557         ss << (info.param.first == AAUDIO_DIRECTION_INPUT ? "INPUT_0x" : "OUTPUT_0x")
558            << std::hex << info.param.second;
559         return ss.str();
560     }
561 
562 protected:
563     void testSetChannelMaskAndCount(aaudio_direction_t direction,
564                                     aaudio_channel_mask_t channelMask,
565                                     int32_t channelCount,
566                                     bool channelMaskFirst);
567 };
568 
testSetChannelMaskAndCount(aaudio_direction_t direction,aaudio_channel_mask_t channelMask,int32_t channelCount,bool setChannelMaskFirst)569 void AAudioStreamBuilderChannelMaskAndCountTest::testSetChannelMaskAndCount(
570         aaudio_direction_t direction, aaudio_channel_mask_t channelMask,
571         int32_t channelCount, bool setChannelMaskFirst) {
572     AAudioStreamBuilder *aaudioBuilder = nullptr;
573     create_stream_builder(&aaudioBuilder);
574     AAudioStreamBuilder_setDirection(aaudioBuilder, direction);
575     if (setChannelMaskFirst) {
576         AAudioStreamBuilder_setChannelMask(aaudioBuilder, channelMask);
577         AAudioStreamBuilder_setChannelCount(aaudioBuilder, channelCount);
578     } else {
579         AAudioStreamBuilder_setChannelCount(aaudioBuilder, channelCount);
580         AAudioStreamBuilder_setChannelMask(aaudioBuilder, channelMask);
581     }
582     AAudioStream *aaudioStream = nullptr;
583     aaudio_result_t result = AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream);
584     ASSERT_EQ(AAUDIO_OK, result);
585     ASSERT_NE(nullptr, aaudioStream);
586     if (setChannelMaskFirst) {
587         ASSERT_EQ(channelCount, AAudioStream_getChannelCount(aaudioStream));
588         ASSERT_EQ(AAUDIO_UNSPECIFIED, AAudioStream_getChannelMask(aaudioStream));
589     } else {
590         // If channel mask is unspecified, stereo will be returned.
591         ASSERT_EQ(channelMask == AAUDIO_UNSPECIFIED ? AAUDIO_CHANNEL_STEREO : channelMask,
592                   AAudioStream_getChannelMask(aaudioStream));
593         ASSERT_EQ(channelMask == AAUDIO_UNSPECIFIED ? 2 : __builtin_popcount(channelMask),
594                   AAudioStream_getChannelCount(aaudioStream));
595     }
596     ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_delete(aaudioBuilder));
597     if (aaudioStream != nullptr) {
598         ASSERT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream));
599     }
600 }
601 
TEST_P(AAudioStreamBuilderChannelMaskAndCountTest,channelMaskAndCount)602 TEST_P(AAudioStreamBuilderChannelMaskAndCountTest, channelMaskAndCount) {
603     const aaudio_direction_t direction = GetParam().first;
604     if ((direction == AAUDIO_DIRECTION_OUTPUT && !deviceSupportsFeature(FEATURE_PLAYBACK)) ||
605         (direction == AAUDIO_DIRECTION_INPUT && !deviceSupportsFeature(FEATURE_RECORDING))) {
606         return;
607     }
608     const aaudio_channel_mask_t channelMask = GetParam().second;
609 
610     testSetChannelMaskAndCount(direction, channelMask,
611                                2 /*channelCount*/, true /*setChannelMaskFirst*/);
612     testSetChannelMaskAndCount(direction, channelMask,
613                                2 /*channelCount*/, false /*setChannelMaskFirst*/);
614 
615     testSetChannelMaskAndCount(direction, AAUDIO_CHANNEL_5POINT1,
616                                2 /*channelCount*/, true /*setChannelMaskFirst*/);
617     testSetChannelMaskAndCount(direction, AAUDIO_CHANNEL_5POINT1,
618                                2 /*channelCount*/, false /*setChannelMaskFirst*/);
619 }
620 
621 INSTANTIATE_TEST_CASE_P(CMC, AAudioStreamBuilderChannelMaskAndCountTest,
622         ::testing::Values(
623                 std::make_pair(AAUDIO_DIRECTION_OUTPUT, AAUDIO_CHANNEL_MONO),
624                 std::make_pair(AAUDIO_DIRECTION_OUTPUT, AAUDIO_CHANNEL_5POINT1),
625                 std::make_pair(AAUDIO_DIRECTION_OUTPUT, AAUDIO_UNSPECIFIED),
626                 std::make_pair(AAUDIO_DIRECTION_INPUT, AAUDIO_CHANNEL_MONO),
627                 std::make_pair(AAUDIO_DIRECTION_INPUT, AAUDIO_CHANNEL_5POINT1),
628                 std::make_pair(AAUDIO_DIRECTION_INPUT, AAUDIO_UNSPECIFIED)),
629         &AAudioStreamBuilderChannelMaskAndCountTest::getTestName);
630 
631 using CommonCombinationTestParams = std::tuple<aaudio_direction_t,
632                                                aaudio_sharing_mode_t,
633                                                aaudio_performance_mode_t,
634                                                int32_t /*sample rate*/,
635                                                aaudio_format_t,
636                                                aaudio_channel_mask_t>;
637 enum {
638     PARAM_DIRECTION = 0,
639     PARAM_SHARING_MODE,
640     PARAM_PERFORMANCE_MODE,
641     PARAM_SAMPLE_RATE,
642     PARAM_FORMAT,
643     PARAM_CHANNEL_MASK
644 };
645 class AAudioStreamBuilderCommonCombinationTest :
646         public AAudioCtsBase, public ::testing::WithParamInterface<CommonCombinationTestParams> {
647   public:
getTestName(const::testing::TestParamInfo<CommonCombinationTestParams> & info)648     static std::string getTestName(
649             const ::testing::TestParamInfo<CommonCombinationTestParams>& info) {
650         std::stringstream ss;
651         ss << (std::get<PARAM_DIRECTION>(info.param) == AAUDIO_DIRECTION_INPUT ? "INPUT_"
652                                                                                : "OUTPUT_")
653            << sharingModeToString(std::get<PARAM_SHARING_MODE>(info.param)) << "_"
654            << performanceModeToString(std::get<PARAM_PERFORMANCE_MODE>(info.param)) << "_"
655            << "sampleRate_" << std::get<PARAM_SAMPLE_RATE>(info.param) << "_"
656            << "format_0x" << std::hex << std::get<PARAM_FORMAT>(info.param) << "_"
657            << "channelMask_0x" << std::get<PARAM_CHANNEL_MASK>(info.param) << "";
658         return ss.str();
659     }
660 };
661 
TEST_P(AAudioStreamBuilderCommonCombinationTest,openStream)662 TEST_P(AAudioStreamBuilderCommonCombinationTest, openStream) {
663     if (!deviceSupportsFeature(FEATURE_PLAYBACK)) return;
664     AAudioStreamBuilder *aaudioBuilder = nullptr;
665     create_stream_builder(&aaudioBuilder);
666     const auto param = GetParam();
667     AAudioStreamBuilder_setDirection(aaudioBuilder, std::get<PARAM_DIRECTION>(param));
668     AAudioStreamBuilder_setSharingMode(aaudioBuilder, std::get<PARAM_SHARING_MODE>(param));
669     AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, std::get<PARAM_PERFORMANCE_MODE>(param));
670     AAudioStreamBuilder_setSampleRate(aaudioBuilder, std::get<PARAM_SAMPLE_RATE>(param));
671     AAudioStreamBuilder_setFormat(aaudioBuilder, std::get<PARAM_FORMAT>(param));
672     AAudioStreamBuilder_setChannelMask(aaudioBuilder, std::get<PARAM_CHANNEL_MASK>(param));
673     // All the test parameters all reasonable values with different combination. In that case,
674     // it is expected that the opening will be successful.
675     try_opening_audio_stream(aaudioBuilder, Expect::SUCCEED);
676 }
677 
678 INSTANTIATE_TEST_CASE_P(CommonComb, AAudioStreamBuilderCommonCombinationTest,
679         ::testing::Combine(
680                 ::testing::Values(AAUDIO_DIRECTION_OUTPUT, AAUDIO_DIRECTION_INPUT),
681                 ::testing::Values(AAUDIO_SHARING_MODE_SHARED, AAUDIO_SHARING_MODE_EXCLUSIVE),
682                 ::testing::Values(
683                         AAUDIO_PERFORMANCE_MODE_NONE,
684                         AAUDIO_PERFORMANCE_MODE_POWER_SAVING,
685                         AAUDIO_PERFORMANCE_MODE_LOW_LATENCY),
686                 ::testing::Values(// Sample rate
687                         AAUDIO_UNSPECIFIED, 8000, 16000, 44100, 48000, 96000, 192000),
688                 ::testing::Values(
689                         AAUDIO_UNSPECIFIED,
690                         AAUDIO_FORMAT_PCM_I16,
691                         AAUDIO_FORMAT_PCM_FLOAT),
692                 ::testing::Values(AAUDIO_CHANNEL_MONO, AAUDIO_CHANNEL_STEREO)),
693         &AAudioStreamBuilderCommonCombinationTest::getTestName);
694