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