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