1 /*
2 * Copyright 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 #include <gtest/gtest.h>
18
19 #include <aaudio/AAudioExtensions.h>
20 #include <oboe/Oboe.h>
21
22 #include <android/api-level.h>
23 #ifndef __ANDROID_API_S__
24 #define __ANDROID_API_S__ 31
25 #endif
26
27 #ifndef __ANDROID_API_S_V2__
28 #define __ANDROID_API_S_V2__ 32
29 #endif
30
31 using namespace oboe;
32
33 class CallbackSizeMonitor : public AudioStreamCallback {
34 public:
onAudioReady(AudioStream * oboeStream,void * audioData,int32_t numFrames)35 DataCallbackResult onAudioReady(AudioStream *oboeStream, void *audioData, int32_t numFrames) override {
36 framesPerCallback = numFrames;
37 callbackCount++;
38 return DataCallbackResult::Continue;
39 }
40
41 // This is exposed publicly so that the number of frames per callback can be tested.
42 std::atomic<int32_t> framesPerCallback{0};
43 std::atomic<int32_t> callbackCount{0};
44 };
45
46 class StreamOpen : public ::testing::Test {
47
48 protected:
49
openStream()50 bool openStream() {
51 EXPECT_EQ(mStream, nullptr);
52 Result r = mBuilder.openStream(&mStream);
53 EXPECT_EQ(r, Result::OK) << "Failed to open stream " << convertToText(r);
54 EXPECT_EQ(0, openCount) << "Should start with a fresh object every time.";
55 openCount++;
56 return (r == Result::OK);
57 }
58
closeStream()59 bool closeStream() {
60 if (mStream != nullptr){
61 Result r = mStream->close();
62 EXPECT_EQ(r, Result::OK) << "Failed to close stream. " << convertToText(r);
63 usleep(500 * 1000); // give previous stream time to settle
64 mStream = nullptr;
65 return (r == Result::OK);
66 } else {
67 return true;
68 }
69 }
70
checkSampleRateConversionAdvancing(Direction direction)71 void checkSampleRateConversionAdvancing(Direction direction) {
72 CallbackSizeMonitor callback;
73
74 mBuilder.setDirection(direction);
75 if (mBuilder.isAAudioRecommended()) {
76 mBuilder.setAudioApi(AudioApi::AAudio);
77 }
78 mBuilder.setCallback(&callback);
79 mBuilder.setPerformanceMode(PerformanceMode::LowLatency);
80 mBuilder.setSampleRate(44100);
81 mBuilder.setSampleRateConversionQuality(SampleRateConversionQuality::Medium);
82
83 ASSERT_TRUE(openStream());
84
85 ASSERT_EQ(mStream->requestStart(), Result::OK);
86 int timeout = 20;
87 while (callback.framesPerCallback == 0 && timeout > 0) {
88 usleep(50 * 1000);
89 timeout--;
90 }
91
92 // Catch Issue #1166
93 mStream->getTimestamp(CLOCK_MONOTONIC); // should not crash
94 mStream->getTimestamp(CLOCK_MONOTONIC, nullptr, nullptr); // should not crash
95
96 ASSERT_GT(callback.callbackCount, 0);
97 ASSERT_GT(callback.framesPerCallback, 0);
98 ASSERT_EQ(mStream->requestStop(), Result::OK);
99
100 ASSERT_TRUE(closeStream());
101 }
102
103 AudioStreamBuilder mBuilder;
104 AudioStream *mStream = nullptr;
105 int32_t openCount = 0;
106
107 };
108
109 class StreamOpenOutput : public StreamOpen {};
110 class StreamOpenInput : public StreamOpen {};
111
TEST_F(StreamOpenOutput,ForOpenSLESDefaultSampleRateIsUsed)112 TEST_F(StreamOpenOutput, ForOpenSLESDefaultSampleRateIsUsed){
113
114 DefaultStreamValues::SampleRate = 44100;
115 DefaultStreamValues::FramesPerBurst = 192;
116 mBuilder.setAudioApi(AudioApi::OpenSLES);
117 ASSERT_TRUE(openStream());
118 ASSERT_EQ(mStream->getSampleRate(), 44100);
119 ASSERT_TRUE(closeStream());
120 }
121
TEST_F(StreamOpenOutput,ForOpenSLESDefaultFramesPerBurstIsUsed)122 TEST_F(StreamOpenOutput, ForOpenSLESDefaultFramesPerBurstIsUsed){
123
124 DefaultStreamValues::SampleRate = 48000;
125 DefaultStreamValues::FramesPerBurst = 128; // used for low latency
126 mBuilder.setAudioApi(AudioApi::OpenSLES);
127 mBuilder.setPerformanceMode(PerformanceMode::LowLatency);
128 ASSERT_TRUE(openStream());
129 // Some devices like emulators may not support Low Latency
130 if (mStream->getPerformanceMode() == PerformanceMode::LowLatency) {
131 ASSERT_EQ(mStream->getFramesPerBurst(), 128);
132 }
133 ASSERT_TRUE(closeStream());
134 }
135
TEST_F(StreamOpenOutput,ForOpenSLESDefaultChannelCountIsUsed)136 TEST_F(StreamOpenOutput, ForOpenSLESDefaultChannelCountIsUsed){
137
138 DefaultStreamValues::ChannelCount = 1;
139 mBuilder.setAudioApi(AudioApi::OpenSLES);
140 ASSERT_TRUE(openStream());
141 ASSERT_EQ(mStream->getChannelCount(), 1);
142 ASSERT_TRUE(closeStream());
143 }
144
TEST_F(StreamOpenOutput,OutputForOpenSLESPerformanceModeShouldBeNone)145 TEST_F(StreamOpenOutput, OutputForOpenSLESPerformanceModeShouldBeNone){
146 // We will not get a LowLatency stream if we request 16000 Hz.
147 mBuilder.setSampleRate(16000);
148 mBuilder.setPerformanceMode(PerformanceMode::LowLatency);
149 mBuilder.setDirection(Direction::Output);
150 mBuilder.setAudioApi(AudioApi::OpenSLES);
151 ASSERT_TRUE(openStream());
152 ASSERT_EQ((int)mStream->getPerformanceMode(), (int)PerformanceMode::None);
153 ASSERT_TRUE(closeStream());
154 }
155
TEST_F(StreamOpenInput,InputForOpenSLESPerformanceModeShouldBeNone)156 TEST_F(StreamOpenInput, InputForOpenSLESPerformanceModeShouldBeNone){
157 // We will not get a LowLatency stream if we request 16000 Hz.
158 mBuilder.setSampleRate(16000);
159 mBuilder.setPerformanceMode(PerformanceMode::LowLatency);
160 mBuilder.setDirection(Direction::Input);
161 mBuilder.setAudioApi(AudioApi::OpenSLES);
162 ASSERT_TRUE(openStream());
163 ASSERT_EQ((int)mStream->getPerformanceMode(), (int)PerformanceMode::None);
164 ASSERT_TRUE(closeStream());
165 }
166
TEST_F(StreamOpenOutput,ForOpenSlesIllegalFormatRejectedOutput)167 TEST_F(StreamOpenOutput, ForOpenSlesIllegalFormatRejectedOutput) {
168 mBuilder.setAudioApi(AudioApi::OpenSLES);
169 mBuilder.setPerformanceMode(PerformanceMode::LowLatency);
170 mBuilder.setFormat(static_cast<AudioFormat>(666));
171 Result r = mBuilder.openStream(&mStream);
172 EXPECT_NE(r, Result::OK) << "Should not open stream " << convertToText(r);
173 if (mStream != nullptr) {
174 mStream->close(); // just in case it accidentally opened
175 }
176 }
177
TEST_F(StreamOpenInput,ForOpenSlesIllegalFormatRejectedInput)178 TEST_F(StreamOpenInput, ForOpenSlesIllegalFormatRejectedInput) {
179 mBuilder.setAudioApi(AudioApi::OpenSLES);
180 mBuilder.setPerformanceMode(PerformanceMode::LowLatency);
181 mBuilder.setDirection(Direction::Input);
182 mBuilder.setFormat(static_cast<AudioFormat>(666));
183 Result r = mBuilder.openStream(&mStream);
184 EXPECT_NE(r, Result::OK) << "Should not open stream " << convertToText(r);
185 if (mStream != nullptr) {
186 mStream->close(); // just in case it accidentally opened
187 }
188 }
189
190 // Make sure the callback is called with the requested FramesPerCallback
TEST_F(StreamOpenOutput,OpenSLESFramesPerCallback)191 TEST_F(StreamOpenOutput, OpenSLESFramesPerCallback) {
192 const int kRequestedFramesPerCallback = 417;
193 CallbackSizeMonitor callback;
194
195 DefaultStreamValues::SampleRate = 48000;
196 DefaultStreamValues::ChannelCount = 2;
197 DefaultStreamValues::FramesPerBurst = 192;
198 mBuilder.setAudioApi(AudioApi::OpenSLES);
199 mBuilder.setFramesPerCallback(kRequestedFramesPerCallback);
200 mBuilder.setCallback(&callback);
201 ASSERT_TRUE(openStream());
202 ASSERT_EQ(mStream->requestStart(), Result::OK);
203 int timeout = 20;
204 while (callback.framesPerCallback == 0 && timeout > 0) {
205 usleep(50 * 1000);
206 timeout--;
207 }
208 ASSERT_EQ(kRequestedFramesPerCallback, callback.framesPerCallback);
209 ASSERT_EQ(kRequestedFramesPerCallback, mStream->getFramesPerCallback());
210 ASSERT_EQ(mStream->requestStop(), Result::OK);
211 ASSERT_TRUE(closeStream());
212 }
213
214 // Make sure the LowLatency callback has the requested FramesPerCallback.
TEST_F(StreamOpen,AAudioFramesPerCallbackLowLatency)215 TEST_F(StreamOpen, AAudioFramesPerCallbackLowLatency) {
216 const int kRequestedFramesPerCallback = 192;
217 CallbackSizeMonitor callback;
218
219 mBuilder.setAudioApi(AudioApi::AAudio);
220 mBuilder.setFramesPerCallback(kRequestedFramesPerCallback);
221 mBuilder.setCallback(&callback);
222 mBuilder.setPerformanceMode(PerformanceMode::LowLatency);
223 ASSERT_TRUE(openStream());
224 ASSERT_EQ(kRequestedFramesPerCallback, mStream->getFramesPerCallback());
225 ASSERT_EQ(mStream->requestStart(), Result::OK);
226 int timeout = 20;
227 while (callback.framesPerCallback == 0 && timeout > 0) {
228 usleep(50 * 1000);
229 timeout--;
230 }
231 ASSERT_EQ(kRequestedFramesPerCallback, callback.framesPerCallback);
232 ASSERT_EQ(mStream->requestStop(), Result::OK);
233 ASSERT_TRUE(closeStream());
234 }
235
236 // Make sure the regular callback has the requested FramesPerCallback.
TEST_F(StreamOpen,AAudioFramesPerCallbackNone)237 TEST_F(StreamOpen, AAudioFramesPerCallbackNone) {
238 const int kRequestedFramesPerCallback = 1024;
239 CallbackSizeMonitor callback;
240
241 mBuilder.setAudioApi(AudioApi::AAudio);
242 mBuilder.setFramesPerCallback(kRequestedFramesPerCallback);
243 mBuilder.setCallback(&callback);
244 mBuilder.setPerformanceMode(PerformanceMode::None);
245 ASSERT_TRUE(openStream());
246 ASSERT_EQ(kRequestedFramesPerCallback, mStream->getFramesPerCallback());
247 ASSERT_EQ(mStream->requestStart(), Result::OK);
248 int timeout = 20;
249 while (callback.framesPerCallback == 0 && timeout > 0) {
250 usleep(50 * 1000);
251 timeout--;
252 }
253 ASSERT_EQ(kRequestedFramesPerCallback, callback.framesPerCallback);
254 ASSERT_EQ(mStream->requestStop(), Result::OK);
255 ASSERT_TRUE(closeStream());
256 }
257
TEST_F(StreamOpenInput,RecordingFormatUnspecifiedReturnsI16BeforeMarshmallow)258 TEST_F(StreamOpenInput, RecordingFormatUnspecifiedReturnsI16BeforeMarshmallow){
259
260 if (getSdkVersion() < __ANDROID_API_M__){
261 mBuilder.setDirection(Direction::Input);
262 mBuilder.setFormat(AudioFormat::Unspecified);
263 ASSERT_TRUE(openStream());
264 ASSERT_EQ(mStream->getFormat(), AudioFormat::I16);
265 ASSERT_TRUE(closeStream());
266 }
267 }
268
TEST_F(StreamOpenInput,RecordingFormatUnspecifiedReturnsFloatOnMarshmallowAndLater)269 TEST_F(StreamOpenInput, RecordingFormatUnspecifiedReturnsFloatOnMarshmallowAndLater){
270
271 if (getSdkVersion() >= __ANDROID_API_M__){
272 mBuilder.setDirection(Direction::Input);
273 mBuilder.setFormat(AudioFormat::Unspecified);
274 ASSERT_TRUE(openStream());
275 ASSERT_EQ(mStream->getFormat(), AudioFormat::Float);
276 ASSERT_TRUE(closeStream());
277 }
278 }
279
TEST_F(StreamOpenInput,RecordingFormatFloatReturnsErrorBeforeMarshmallow)280 TEST_F(StreamOpenInput, RecordingFormatFloatReturnsErrorBeforeMarshmallow){
281
282 if (getSdkVersion() < __ANDROID_API_M__){
283 mBuilder.setDirection(Direction::Input);
284 mBuilder.setFormat(AudioFormat::Float);
285 Result r = mBuilder.openStream(&mStream);
286 ASSERT_EQ(r, Result::ErrorInvalidFormat) << convertToText(r);
287 ASSERT_TRUE(closeStream());
288 }
289 }
290
TEST_F(StreamOpenInput,RecordingFormatFloatReturnsFloatOnMarshmallowAndLater)291 TEST_F(StreamOpenInput, RecordingFormatFloatReturnsFloatOnMarshmallowAndLater){
292
293 if (getSdkVersion() >= __ANDROID_API_M__){
294 mBuilder.setDirection(Direction::Input);
295 mBuilder.setFormat(AudioFormat::Float);
296 ASSERT_TRUE(openStream());
297 ASSERT_EQ(mStream->getFormat(), AudioFormat::Float);
298 ASSERT_TRUE(closeStream());
299 }
300 }
301
TEST_F(StreamOpenInput,RecordingFormatI16ReturnsI16)302 TEST_F(StreamOpenInput, RecordingFormatI16ReturnsI16){
303
304 mBuilder.setDirection(Direction::Input);
305 mBuilder.setFormat(AudioFormat::I16);
306 ASSERT_TRUE(openStream());
307 ASSERT_EQ(mStream->getFormat(), AudioFormat::I16);
308 ASSERT_TRUE(closeStream());
309 }
310
TEST_F(StreamOpenOutput,PlaybackFormatUnspecifiedReturnsI16BeforeLollipop)311 TEST_F(StreamOpenOutput, PlaybackFormatUnspecifiedReturnsI16BeforeLollipop){
312
313 if (getSdkVersion() < __ANDROID_API_L__){
314 mBuilder.setDirection(Direction::Output);
315 mBuilder.setFormat(AudioFormat::Unspecified);
316 ASSERT_TRUE(openStream());
317 ASSERT_EQ(mStream->getFormat(), AudioFormat::I16);
318 ASSERT_TRUE(closeStream());
319 }
320 }
321
TEST_F(StreamOpenOutput,PlaybackFormatUnspecifiedReturnsFloatOnLollipopAndLater)322 TEST_F(StreamOpenOutput, PlaybackFormatUnspecifiedReturnsFloatOnLollipopAndLater){
323
324 if (getSdkVersion() >= __ANDROID_API_L__){
325 mBuilder.setDirection(Direction::Output);
326 mBuilder.setFormat(AudioFormat::Unspecified);
327 ASSERT_TRUE(openStream());
328 ASSERT_EQ(mStream->getFormat(), AudioFormat::Float);
329 ASSERT_TRUE(closeStream());
330 }
331 }
332
TEST_F(StreamOpenOutput,PlaybackFormatFloatReturnsErrorBeforeLollipop)333 TEST_F(StreamOpenOutput, PlaybackFormatFloatReturnsErrorBeforeLollipop){
334
335 if (getSdkVersion() < __ANDROID_API_L__){
336 mBuilder.setDirection(Direction::Output);
337 mBuilder.setFormat(AudioFormat::Float);
338 Result r = mBuilder.openStream(&mStream);
339 ASSERT_EQ(r, Result::ErrorInvalidFormat);
340 ASSERT_TRUE(closeStream());
341 }
342 }
343
TEST_F(StreamOpenOutput,PlaybackFormatFloatReturnsFloatWithFormatConversionAllowed)344 TEST_F(StreamOpenOutput, PlaybackFormatFloatReturnsFloatWithFormatConversionAllowed){
345 mBuilder.setDirection(Direction::Output);
346 mBuilder.setFormat(AudioFormat::Float);
347 mBuilder.setFormatConversionAllowed(true);
348 ASSERT_TRUE(openStream());
349 ASSERT_EQ(mStream->getFormat(), AudioFormat::Float);
350 ASSERT_TRUE(closeStream());
351 }
352
TEST_F(StreamOpenOutput,PlaybackFormatFloatReturnsFloatOnLollipopAndLater)353 TEST_F(StreamOpenOutput, PlaybackFormatFloatReturnsFloatOnLollipopAndLater){
354
355 if (getSdkVersion() >= __ANDROID_API_L__){
356 mBuilder.setDirection(Direction::Output);
357 mBuilder.setFormat(AudioFormat::Float);
358 ASSERT_TRUE(openStream());
359 ASSERT_EQ(mStream->getFormat(), AudioFormat::Float);
360 ASSERT_TRUE(closeStream());
361 }
362 }
363
TEST_F(StreamOpenOutput,PlaybackFormatI16ReturnsI16)364 TEST_F(StreamOpenOutput, PlaybackFormatI16ReturnsI16) {
365 mBuilder.setDirection(Direction::Output);
366 mBuilder.setFormat(AudioFormat::I16);
367 ASSERT_TRUE(openStream());
368 ASSERT_EQ(mStream->getFormat(), AudioFormat::I16);
369 ASSERT_TRUE(closeStream());
370 }
371
TEST_F(StreamOpenOutput,OpenCloseLowLatencyStream)372 TEST_F(StreamOpenOutput, OpenCloseLowLatencyStream){
373 mBuilder.setDirection(Direction::Output);
374 mBuilder.setPerformanceMode(PerformanceMode::LowLatency);
375 float *buf = new float[100];
376 ASSERT_TRUE(openStream());
377 delete[] buf;
378 ASSERT_TRUE(closeStream());
379 }
380
TEST_F(StreamOpenOutput,LowLatencyStreamHasSmallBufferSize)381 TEST_F(StreamOpenOutput, LowLatencyStreamHasSmallBufferSize){
382
383 if (mBuilder.isAAudioRecommended()) {
384 mBuilder.setDirection(Direction::Output);
385 mBuilder.setPerformanceMode(PerformanceMode::LowLatency);
386 ASSERT_TRUE(openStream());
387 int32_t bufferSize = mStream->getBufferSizeInFrames();
388 int32_t burst = mStream->getFramesPerBurst();
389 ASSERT_TRUE(closeStream());
390 ASSERT_LE(bufferSize, burst * 3);
391 }
392 }
393
394 // Make sure the parameters get copied from the child stream.
TEST_F(StreamOpenOutput,AAudioOutputSampleRate44100FilterConfiguration)395 TEST_F(StreamOpenOutput, AAudioOutputSampleRate44100FilterConfiguration) {
396 if (mBuilder.isAAudioRecommended()) {
397 mBuilder.setDirection(Direction::Output);
398 mBuilder.setPerformanceMode(PerformanceMode::LowLatency);
399 mBuilder.setSharingMode(SharingMode::Exclusive);
400 // Try to force the use of a FilterAudioStream by requesting conversion.
401 mBuilder.setSampleRate(44100);
402 mBuilder.setSampleRateConversionQuality(SampleRateConversionQuality::Medium);
403 ASSERT_TRUE(openStream());
404 if (getSdkVersion() >= __ANDROID_API_U__) {
405 ASSERT_LT(0, mStream->getHardwareSampleRate());
406 ASSERT_LT(0, mStream->getHardwareChannelCount());
407 ASSERT_LT(0, (int)mStream->getHardwareFormat());
408 }
409 // If MMAP is not supported then we cannot get an EXCLUSIVE mode stream.
410 if (!AAudioExtensions::getInstance().isMMapSupported()) {
411 ASSERT_NE(SharingMode::Exclusive, mStream->getSharingMode()); // IMPOSSIBLE
412 }
413 ASSERT_TRUE(closeStream());
414 }
415 }
416
417 // See if sample rate conversion by Oboe is calling the callback.
TEST_F(StreamOpenOutput,AAudioOutputSampleRate44100)418 TEST_F(StreamOpenOutput, AAudioOutputSampleRate44100) {
419 checkSampleRateConversionAdvancing(Direction::Output);
420 }
421
422 // See if sample rate conversion by Oboe is calling the callback.
TEST_F(StreamOpenInput,AAudioInputSampleRate44100)423 TEST_F(StreamOpenInput, AAudioInputSampleRate44100) {
424 checkSampleRateConversionAdvancing(Direction::Input);
425 }
426
TEST_F(StreamOpenOutput,AAudioOutputSetPackageName)427 TEST_F(StreamOpenOutput, AAudioOutputSetPackageName){
428 if (getSdkVersion() >= __ANDROID_API_S__){
429 mBuilder.setAudioApi(AudioApi::AAudio);
430 mBuilder.setPackageName("com.google.oboe.tests.unittestrunner");
431 ASSERT_TRUE(openStream());
432 ASSERT_EQ(mStream->requestStart(), Result::OK);
433 ASSERT_TRUE(closeStream());
434 }
435 }
436
TEST_F(StreamOpenInput,AAudioInputSetPackageName)437 TEST_F(StreamOpenInput, AAudioInputSetPackageName){
438 if (getSdkVersion() >= __ANDROID_API_S__){
439 mBuilder.setDirection(Direction::Input);
440 mBuilder.setAudioApi(AudioApi::AAudio);
441 mBuilder.setPackageName("com.google.oboe.tests.unittestrunner");
442 ASSERT_TRUE(openStream());
443 ASSERT_EQ(mStream->requestStart(), Result::OK);
444 ASSERT_TRUE(closeStream());
445 }
446 }
447
TEST_F(StreamOpenOutput,AAudioOutputSetAttributionTag)448 TEST_F(StreamOpenOutput, AAudioOutputSetAttributionTag){
449 if (getSdkVersion() >= __ANDROID_API_S__){
450 mBuilder.setAudioApi(AudioApi::AAudio);
451 mBuilder.setAttributionTag("TestSetOutputAttributionTag");
452 ASSERT_TRUE(openStream());
453 ASSERT_EQ(mStream->requestStart(), Result::OK);
454 ASSERT_TRUE(closeStream());
455 }
456 }
457
TEST_F(StreamOpenInput,AAudioInputSetAttributionTag)458 TEST_F(StreamOpenInput, AAudioInputSetAttributionTag){
459 if (getSdkVersion() >= __ANDROID_API_S__){
460 mBuilder.setDirection(Direction::Input);
461 mBuilder.setAudioApi(AudioApi::AAudio);
462 mBuilder.setAttributionTag("TestSetInputAttributionTag");
463 ASSERT_TRUE(openStream());
464 ASSERT_EQ(mStream->requestStart(), Result::OK);
465 ASSERT_TRUE(closeStream());
466 }
467 }
468
TEST_F(StreamOpenInput,AAudioInputSetSpatializationBehavior)469 TEST_F(StreamOpenInput, AAudioInputSetSpatializationBehavior) {
470 mBuilder.setDirection(Direction::Input);
471 mBuilder.setSpatializationBehavior(SpatializationBehavior::Auto);
472 ASSERT_TRUE(openStream());
473 if (getSdkVersion() >= __ANDROID_API_S_V2__){
474 ASSERT_EQ(mStream->getSpatializationBehavior(), SpatializationBehavior::Auto);
475 } else {
476 ASSERT_EQ(mStream->getSpatializationBehavior(), SpatializationBehavior::Never);
477 }
478 ASSERT_TRUE(closeStream());
479 }
480
TEST_F(StreamOpenOutput,AAudioOutputSetSpatializationBehavior)481 TEST_F(StreamOpenOutput, AAudioOutputSetSpatializationBehavior) {
482 mBuilder.setDirection(Direction::Output);
483 mBuilder.setSpatializationBehavior(SpatializationBehavior::Never);
484 ASSERT_TRUE(openStream());
485 ASSERT_EQ(mStream->getSpatializationBehavior(), SpatializationBehavior::Never);
486 ASSERT_TRUE(closeStream());
487 }
488
TEST_F(StreamOpenOutput,OpenSLESOutputSetSpatializationBehavior)489 TEST_F(StreamOpenOutput, OpenSLESOutputSetSpatializationBehavior) {
490 mBuilder.setDirection(Direction::Output);
491 mBuilder.setAudioApi(AudioApi::OpenSLES);
492 mBuilder.setSpatializationBehavior(SpatializationBehavior::Auto);
493 ASSERT_TRUE(openStream());
494 ASSERT_EQ(mStream->getSpatializationBehavior(), SpatializationBehavior::Never);
495 ASSERT_TRUE(closeStream());
496 }
497
TEST_F(StreamOpenInput,AAudioInputSetSpatializationBehaviorUnspecified)498 TEST_F(StreamOpenInput, AAudioInputSetSpatializationBehaviorUnspecified) {
499 mBuilder.setDirection(Direction::Input);
500 mBuilder.setSpatializationBehavior(SpatializationBehavior::Unspecified);
501 ASSERT_TRUE(openStream());
502 ASSERT_EQ(mStream->getSpatializationBehavior(), SpatializationBehavior::Never);
503 ASSERT_TRUE(closeStream());
504 }
505
TEST_F(StreamOpenOutput,AAudioOutputSetSpatializationBehaviorUnspecified)506 TEST_F(StreamOpenOutput, AAudioOutputSetSpatializationBehaviorUnspecified) {
507 mBuilder.setDirection(Direction::Output);
508 mBuilder.setSpatializationBehavior(SpatializationBehavior::Unspecified);
509 ASSERT_TRUE(openStream());
510 ASSERT_EQ(mStream->getSpatializationBehavior(), SpatializationBehavior::Never);
511 ASSERT_TRUE(closeStream());
512 }
513
TEST_F(StreamOpenInput,AAudioInputSetIsContentSpatialized)514 TEST_F(StreamOpenInput, AAudioInputSetIsContentSpatialized) {
515 mBuilder.setDirection(Direction::Input);
516 mBuilder.setIsContentSpatialized(true);
517 ASSERT_TRUE(openStream());
518 ASSERT_EQ(mStream->isContentSpatialized(), true);
519 ASSERT_TRUE(closeStream());
520 }
521
TEST_F(StreamOpenOutput,AAudioOutputSetIsContentSpatialized)522 TEST_F(StreamOpenOutput, AAudioOutputSetIsContentSpatialized) {
523 mBuilder.setDirection(Direction::Output);
524 mBuilder.setIsContentSpatialized(true);
525 ASSERT_TRUE(openStream());
526 ASSERT_EQ(mStream->isContentSpatialized(), true);
527 ASSERT_TRUE(closeStream());
528 }
529
TEST_F(StreamOpenOutput,OpenSLESOutputSetIsContentSpatialized)530 TEST_F(StreamOpenOutput, OpenSLESOutputSetIsContentSpatialized) {
531 mBuilder.setDirection(Direction::Output);
532 mBuilder.setAudioApi(AudioApi::OpenSLES);
533 mBuilder.setIsContentSpatialized(true);
534 ASSERT_TRUE(openStream());
535 ASSERT_EQ(mStream->isContentSpatialized(), true);
536 ASSERT_TRUE(closeStream());
537 }
538
TEST_F(StreamOpenOutput,AAudioOutputSetIsContentSpatializedFalse)539 TEST_F(StreamOpenOutput, AAudioOutputSetIsContentSpatializedFalse) {
540 mBuilder.setDirection(Direction::Output);
541 mBuilder.setIsContentSpatialized(false);
542 ASSERT_TRUE(openStream());
543 ASSERT_EQ(mStream->isContentSpatialized(), false);
544 ASSERT_TRUE(closeStream());
545 }
546
TEST_F(StreamOpenOutput,AAudioOutputSetIsContentSpatializedUnspecified)547 TEST_F(StreamOpenOutput, AAudioOutputSetIsContentSpatializedUnspecified) {
548 mBuilder.setDirection(Direction::Output);
549 ASSERT_TRUE(openStream());
550 ASSERT_EQ(mStream->isContentSpatialized(), false);
551 ASSERT_TRUE(closeStream());
552 }
553
TEST_F(StreamOpenInput,AAudioInputSetIsContentSpatializedUnspecified)554 TEST_F(StreamOpenInput, AAudioInputSetIsContentSpatializedUnspecified) {
555 mBuilder.setDirection(Direction::Input);
556 ASSERT_TRUE(openStream());
557 ASSERT_EQ(mStream->isContentSpatialized(), false);
558 ASSERT_TRUE(closeStream());
559 }
560
TEST_F(StreamOpenOutput,OutputForOpenSLESPerformanceModeNoneGetBufferSizeInFrames)561 TEST_F(StreamOpenOutput, OutputForOpenSLESPerformanceModeNoneGetBufferSizeInFrames){
562 mBuilder.setPerformanceMode(PerformanceMode::None);
563 mBuilder.setAudioApi(AudioApi::OpenSLES);
564 ASSERT_TRUE(openStream());
565 EXPECT_GT(mStream->getBufferSizeInFrames(), 0);
566 ASSERT_TRUE(closeStream());
567 }
568
TEST_F(StreamOpenOutput,OboeExtensions)569 TEST_F(StreamOpenOutput, OboeExtensions){
570 if (OboeExtensions::isMMapSupported()) {
571 ASSERT_EQ(OboeExtensions::setMMapEnabled(true), 0);
572 ASSERT_TRUE(OboeExtensions::isMMapEnabled());
573
574 ASSERT_EQ(OboeExtensions::setMMapEnabled(false), 0);
575 ASSERT_FALSE(OboeExtensions::isMMapEnabled());
576 ASSERT_TRUE(openStream());
577 EXPECT_FALSE(OboeExtensions::isMMapUsed(mStream));
578 ASSERT_TRUE(closeStream());
579
580 ASSERT_EQ(OboeExtensions::setMMapEnabled(true), 0);
581 ASSERT_TRUE(OboeExtensions::isMMapEnabled());
582 }
583 }
584
TEST_F(StreamOpenInput,AAudioInputSetPrivacySensitiveModeUnspecifiedUnprocessed)585 TEST_F(StreamOpenInput, AAudioInputSetPrivacySensitiveModeUnspecifiedUnprocessed){
586 if (getSdkVersion() >= __ANDROID_API_R__){
587 mBuilder.setDirection(Direction::Input);
588 mBuilder.setAudioApi(AudioApi::AAudio);
589 mBuilder.setInputPreset(InputPreset::Unprocessed);
590 ASSERT_TRUE(openStream());
591 ASSERT_EQ(mStream->getPrivacySensitiveMode(), PrivacySensitiveMode::Disabled);
592 ASSERT_TRUE(closeStream());
593 }
594 }
595
TEST_F(StreamOpenInput,AAudioInputSetPrivacySensitiveModeUnspecifiedVoiceCommunication)596 TEST_F(StreamOpenInput, AAudioInputSetPrivacySensitiveModeUnspecifiedVoiceCommunication){
597 if (getSdkVersion() >= __ANDROID_API_R__){
598 mBuilder.setDirection(Direction::Input);
599 mBuilder.setAudioApi(AudioApi::AAudio);
600 mBuilder.setInputPreset(InputPreset::VoiceCommunication);
601 ASSERT_TRUE(openStream());
602 ASSERT_EQ(mStream->getPrivacySensitiveMode(), PrivacySensitiveMode::Enabled);
603 ASSERT_TRUE(closeStream());
604 }
605 }
606
TEST_F(StreamOpenInput,AAudioInputSetPrivacySensitiveModeVoiceDisabled)607 TEST_F(StreamOpenInput, AAudioInputSetPrivacySensitiveModeVoiceDisabled){
608 if (getSdkVersion() >= __ANDROID_API_R__){
609 mBuilder.setDirection(Direction::Input);
610 mBuilder.setAudioApi(AudioApi::AAudio);
611 mBuilder.setInputPreset(InputPreset::VoiceCommunication);
612 mBuilder.setPrivacySensitiveMode(PrivacySensitiveMode::Disabled);
613 ASSERT_TRUE(openStream());
614 ASSERT_EQ(mStream->getPrivacySensitiveMode(), PrivacySensitiveMode::Disabled);
615 ASSERT_TRUE(closeStream());
616 }
617 }
618
TEST_F(StreamOpenInput,AAudioInputSetPrivacySensitiveModeUnprocessedEnabled)619 TEST_F(StreamOpenInput, AAudioInputSetPrivacySensitiveModeUnprocessedEnabled){
620 if (getSdkVersion() >= __ANDROID_API_R__){
621 mBuilder.setDirection(Direction::Input);
622 mBuilder.setAudioApi(AudioApi::AAudio);
623 mBuilder.setInputPreset(InputPreset::Unprocessed);
624 mBuilder.setPrivacySensitiveMode(PrivacySensitiveMode::Enabled);
625 ASSERT_TRUE(openStream());
626 ASSERT_EQ(mStream->getPrivacySensitiveMode(), PrivacySensitiveMode::Enabled);
627 ASSERT_TRUE(closeStream());
628 }
629 }
630
TEST_F(StreamOpenOutput,AAudioOutputSetPrivacySensitiveModeGetsUnspecified)631 TEST_F(StreamOpenOutput, AAudioOutputSetPrivacySensitiveModeGetsUnspecified){
632 if (getSdkVersion() >= __ANDROID_API_R__){
633 mBuilder.setDirection(Direction::Output);
634 mBuilder.setAudioApi(AudioApi::AAudio);
635 mBuilder.setPrivacySensitiveMode(PrivacySensitiveMode::Enabled);
636 ASSERT_TRUE(openStream());
637 ASSERT_EQ(mStream->getPrivacySensitiveMode(), PrivacySensitiveMode::Unspecified);
638 ASSERT_TRUE(closeStream());
639 }
640 }
641
TEST_F(StreamOpenInput,OpenSLESInputSetPrivacySensitiveModeDoesNotCrash)642 TEST_F(StreamOpenInput, OpenSLESInputSetPrivacySensitiveModeDoesNotCrash){
643 mBuilder.setDirection(Direction::Input);
644 mBuilder.setAudioApi(AudioApi::OpenSLES);
645 mBuilder.setInputPreset(InputPreset::Unprocessed);
646 mBuilder.setPrivacySensitiveMode(PrivacySensitiveMode::Enabled);
647 ASSERT_TRUE(openStream());
648 ASSERT_EQ(mStream->getPrivacySensitiveMode(), PrivacySensitiveMode::Unspecified);
649 ASSERT_TRUE(closeStream());
650 }
651
TEST_F(StreamOpenInput,OldAndroidVersionInputSetPrivacySensitiveModeDoesNotCrash)652 TEST_F(StreamOpenInput, OldAndroidVersionInputSetPrivacySensitiveModeDoesNotCrash){
653 if (getSdkVersion() < __ANDROID_API_R__) {
654 mBuilder.setDirection(Direction::Input);
655 mBuilder.setInputPreset(InputPreset::Unprocessed);
656 mBuilder.setPrivacySensitiveMode(PrivacySensitiveMode::Enabled);
657 ASSERT_TRUE(openStream());
658 ASSERT_EQ(mStream->getPrivacySensitiveMode(), PrivacySensitiveMode::Unspecified);
659 ASSERT_TRUE(closeStream());
660 }
661 }
662
TEST_F(StreamOpenOutput,AAudioOutputSetAllowedCapturePolicyUnspecifiedGetsAll)663 TEST_F(StreamOpenOutput, AAudioOutputSetAllowedCapturePolicyUnspecifiedGetsAll){
664 if (getSdkVersion() >= __ANDROID_API_Q__){
665 mBuilder.setDirection(Direction::Output);
666 mBuilder.setAudioApi(AudioApi::AAudio);
667 mBuilder.setAllowedCapturePolicy(AllowedCapturePolicy::Unspecified);
668 ASSERT_TRUE(openStream());
669 ASSERT_EQ(mStream->getAllowedCapturePolicy(), AllowedCapturePolicy::All);
670 ASSERT_TRUE(closeStream());
671 }
672 }
673
TEST_F(StreamOpenOutput,AAudioOutputSetAllowedCapturePolicyAll)674 TEST_F(StreamOpenOutput, AAudioOutputSetAllowedCapturePolicyAll){
675 if (getSdkVersion() >= __ANDROID_API_Q__){
676 mBuilder.setDirection(Direction::Output);
677 mBuilder.setAudioApi(AudioApi::AAudio);
678 mBuilder.setAllowedCapturePolicy(AllowedCapturePolicy::All);
679 ASSERT_TRUE(openStream());
680 ASSERT_EQ(mStream->getAllowedCapturePolicy(), AllowedCapturePolicy::All);
681 ASSERT_TRUE(closeStream());
682 }
683 }
684
TEST_F(StreamOpenOutput,AAudioOutputSetAllowedCapturePolicySystem)685 TEST_F(StreamOpenOutput, AAudioOutputSetAllowedCapturePolicySystem){
686 if (getSdkVersion() >= __ANDROID_API_Q__){
687 mBuilder.setDirection(Direction::Output);
688 mBuilder.setAudioApi(AudioApi::AAudio);
689 mBuilder.setAllowedCapturePolicy(AllowedCapturePolicy::System);
690 ASSERT_TRUE(openStream());
691 ASSERT_EQ(mStream->getAllowedCapturePolicy(), AllowedCapturePolicy::System);
692 ASSERT_TRUE(closeStream());
693 }
694 }
695
TEST_F(StreamOpenOutput,AAudioOutputSetAllowedCapturePolicyNone)696 TEST_F(StreamOpenOutput, AAudioOutputSetAllowedCapturePolicyNone){
697 if (getSdkVersion() >= __ANDROID_API_Q__){
698 mBuilder.setDirection(Direction::Output);
699 mBuilder.setAudioApi(AudioApi::AAudio);
700 mBuilder.setAllowedCapturePolicy(AllowedCapturePolicy::None);
701 ASSERT_TRUE(openStream());
702 ASSERT_EQ(mStream->getAllowedCapturePolicy(), AllowedCapturePolicy::None);
703 ASSERT_TRUE(closeStream());
704 }
705 }
706
TEST_F(StreamOpenOutput,AAudioOutputDoNotSetAllowedCapturePolicy)707 TEST_F(StreamOpenOutput, AAudioOutputDoNotSetAllowedCapturePolicy){
708 mBuilder.setDirection(Direction::Output);
709 mBuilder.setAudioApi(AudioApi::AAudio);
710 ASSERT_TRUE(openStream());
711 if (getSdkVersion() >= __ANDROID_API_Q__){
712 ASSERT_EQ(mStream->getAllowedCapturePolicy(), AllowedCapturePolicy::All);
713 } else {
714 ASSERT_EQ(mStream->getAllowedCapturePolicy(), AllowedCapturePolicy::Unspecified);
715 }
716 ASSERT_TRUE(closeStream());
717 }
718
TEST_F(StreamOpenOutput,OpenSLESOutputSetAllowedCapturePolicyAllGetsUnspecified)719 TEST_F(StreamOpenOutput, OpenSLESOutputSetAllowedCapturePolicyAllGetsUnspecified){
720 mBuilder.setDirection(Direction::Output);
721 mBuilder.setAudioApi(AudioApi::OpenSLES);
722 mBuilder.setAllowedCapturePolicy(AllowedCapturePolicy::All);
723 ASSERT_TRUE(openStream());
724 ASSERT_EQ(mStream->getAllowedCapturePolicy(), AllowedCapturePolicy::Unspecified);
725 ASSERT_TRUE(closeStream());
726 }
727
TEST_F(StreamOpenOutput,AAudioBeforeQOutputSetAllowedCapturePolicyAllGetsUnspecified)728 TEST_F(StreamOpenOutput, AAudioBeforeQOutputSetAllowedCapturePolicyAllGetsUnspecified){
729 if (getSdkVersion() < __ANDROID_API_Q__){
730 mBuilder.setDirection(Direction::Output);
731 mBuilder.setAudioApi(AudioApi::AAudio);
732 mBuilder.setAllowedCapturePolicy(AllowedCapturePolicy::All);
733 ASSERT_TRUE(openStream());
734 ASSERT_EQ(mStream->getAllowedCapturePolicy(), AllowedCapturePolicy::Unspecified);
735 ASSERT_TRUE(closeStream());
736 }
737 }
738
TEST_F(StreamOpenInput,AAudioInputSetAllowedCapturePolicyAllGetsUnspecified)739 TEST_F(StreamOpenInput, AAudioInputSetAllowedCapturePolicyAllGetsUnspecified){
740 mBuilder.setDirection(Direction::Input);
741 mBuilder.setAllowedCapturePolicy(AllowedCapturePolicy::All);
742 ASSERT_TRUE(openStream());
743 ASSERT_EQ(mStream->getAllowedCapturePolicy(), AllowedCapturePolicy::Unspecified);
744 ASSERT_TRUE(closeStream());
745 }
746