Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright (C) 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 // Test various AAudio features including AAudioStream_setBufferSizeInFrames().
     18 
     19 #include <condition_variable>
     20 #include <mutex>
     21 #include <stdio.h>
     22 
     23 #include <android-base/macros.h>
     24 #include <aaudio/AAudio.h>
     25 
     26 #include <gtest/gtest.h>
     27 #include <unistd.h>
     28 
     29 // Callback function that does nothing.
     30 aaudio_data_callback_result_t NoopDataCallbackProc(
     31         AAudioStream *stream,
     32         void *userData,
     33         void *audioData,
     34         int32_t numFrames
     35 ) {
     36     (void) stream;
     37     (void) userData;
     38     (void) audioData;
     39     (void) numFrames;
     40     return AAUDIO_CALLBACK_RESULT_CONTINUE;
     41 }
     42 
     43 // Test AAudioStream_setBufferSizeInFrames()
     44 
     45 constexpr int64_t NANOS_PER_MILLISECOND = 1000 * 1000;
     46 
     47 enum FunctionToCall {
     48     CALL_START, CALL_STOP, CALL_PAUSE, CALL_FLUSH
     49 };
     50 
     51 void checkStateTransition(aaudio_performance_mode_t perfMode,
     52                           aaudio_stream_state_t originalState,
     53                           FunctionToCall functionToCall,
     54                           aaudio_result_t expectedResult,
     55                           aaudio_stream_state_t expectedState) {
     56     AAudioStreamBuilder *aaudioBuilder = nullptr;
     57     AAudioStream *aaudioStream = nullptr;
     58 
     59     // Use an AAudioStreamBuilder to contain requested parameters.
     60     ASSERT_EQ(AAUDIO_OK, AAudio_createStreamBuilder(&aaudioBuilder));
     61 
     62     // Request stream properties.
     63     AAudioStreamBuilder_setDataCallback(aaudioBuilder, NoopDataCallbackProc, nullptr);
     64     AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, perfMode);
     65 
     66     // Create an AAudioStream using the Builder.
     67     ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream));
     68 
     69     // Verify Open State
     70     aaudio_stream_state_t state = AAUDIO_STREAM_STATE_UNKNOWN;
     71     EXPECT_EQ(AAUDIO_OK, AAudioStream_waitForStateChange(aaudioStream,
     72                                                          AAUDIO_STREAM_STATE_UNKNOWN, &state,
     73                                                          1000 * NANOS_PER_MILLISECOND));
     74     EXPECT_EQ(AAUDIO_STREAM_STATE_OPEN, state);
     75 
     76     // Put stream into desired state.
     77     aaudio_stream_state_t inputState = AAUDIO_STREAM_STATE_UNINITIALIZED;
     78     if (originalState != AAUDIO_STREAM_STATE_OPEN) {
     79 
     80         ASSERT_EQ(AAUDIO_OK, AAudioStream_requestStart(aaudioStream));
     81 
     82         if (originalState != AAUDIO_STREAM_STATE_STARTING) {
     83 
     84             ASSERT_EQ(AAUDIO_OK, AAudioStream_waitForStateChange(aaudioStream,
     85                                                                  AAUDIO_STREAM_STATE_STARTING,
     86                                                                  &state,
     87                                                                  1000 * NANOS_PER_MILLISECOND));
     88             ASSERT_EQ(AAUDIO_STREAM_STATE_STARTED, state);
     89 
     90             if (originalState == AAUDIO_STREAM_STATE_STOPPING) {
     91                 ASSERT_EQ(AAUDIO_OK, AAudioStream_requestStop(aaudioStream));
     92             } else if (originalState == AAUDIO_STREAM_STATE_STOPPED) {
     93                 ASSERT_EQ(AAUDIO_OK, AAudioStream_requestStop(aaudioStream));
     94                 inputState = AAUDIO_STREAM_STATE_STOPPING;
     95             } else if (originalState == AAUDIO_STREAM_STATE_PAUSING) {
     96                 ASSERT_EQ(AAUDIO_OK, AAudioStream_requestPause(aaudioStream));
     97             } else if (originalState == AAUDIO_STREAM_STATE_PAUSED) {
     98                 ASSERT_EQ(AAUDIO_OK, AAudioStream_requestPause(aaudioStream));
     99                 inputState = AAUDIO_STREAM_STATE_PAUSING;
    100             }
    101         }
    102     }
    103 
    104     // Wait until past transitional state.
    105     if (inputState != AAUDIO_STREAM_STATE_UNINITIALIZED) {
    106         ASSERT_EQ(AAUDIO_OK, AAudioStream_waitForStateChange(aaudioStream,
    107                                                              inputState,
    108                                                              &state,
    109                                                              1000 * NANOS_PER_MILLISECOND));
    110         ASSERT_EQ(originalState, state);
    111     }
    112 
    113     aaudio_stream_state_t transitionalState = originalState;
    114     switch(functionToCall) {
    115         case FunctionToCall::CALL_START:
    116             EXPECT_EQ(expectedResult, AAudioStream_requestStart(aaudioStream));
    117             transitionalState = AAUDIO_STREAM_STATE_STARTING;
    118             break;
    119         case FunctionToCall::CALL_STOP:
    120             EXPECT_EQ(expectedResult, AAudioStream_requestStop(aaudioStream));
    121             transitionalState = AAUDIO_STREAM_STATE_STOPPING;
    122             break;
    123         case FunctionToCall::CALL_PAUSE:
    124             EXPECT_EQ(expectedResult, AAudioStream_requestPause(aaudioStream));
    125             transitionalState = AAUDIO_STREAM_STATE_PAUSING;
    126             break;
    127         case FunctionToCall::CALL_FLUSH:
    128             EXPECT_EQ(expectedResult, AAudioStream_requestFlush(aaudioStream));
    129             transitionalState = AAUDIO_STREAM_STATE_FLUSHING;
    130             break;
    131     }
    132 
    133     EXPECT_EQ(AAUDIO_OK, AAudioStream_waitForStateChange(aaudioStream,
    134                                                          transitionalState,
    135                                                          &state,
    136                                                          1000 * NANOS_PER_MILLISECOND));
    137     // We should not change state when a function fails.
    138     if (expectedResult != AAUDIO_OK) {
    139         ASSERT_EQ(originalState, expectedState);
    140     }
    141     EXPECT_EQ(expectedState, state);
    142     if (state != expectedState) {
    143         printf("ERROR - expected %s, actual = %s\n",
    144                 AAudio_convertStreamStateToText(expectedState),
    145                 AAudio_convertStreamStateToText(state));
    146         fflush(stdout);
    147     }
    148 
    149     AAudioStream_close(aaudioStream);
    150     AAudioStreamBuilder_delete(aaudioBuilder);
    151 }
    152 
    153 // TODO Use parameterized tests instead of these individual specific tests.
    154 
    155 // OPEN =================================================================
    156 TEST(test_various, aaudio_state_lowlat_open_start) {
    157     checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
    158             AAUDIO_STREAM_STATE_OPEN,
    159             FunctionToCall::CALL_START,
    160             AAUDIO_OK,
    161             AAUDIO_STREAM_STATE_STARTED);
    162 }
    163 
    164 TEST(test_various, aaudio_state_none_open_start) {
    165     checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
    166             AAUDIO_STREAM_STATE_OPEN,
    167             FunctionToCall::CALL_START,
    168             AAUDIO_OK,
    169             AAUDIO_STREAM_STATE_STARTED);
    170 }
    171 
    172 TEST(test_various, aaudio_state_lowlat_open_stop) {
    173     checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
    174             AAUDIO_STREAM_STATE_OPEN,
    175             FunctionToCall::CALL_STOP,
    176             AAUDIO_OK,
    177             AAUDIO_STREAM_STATE_STOPPED);
    178 }
    179 
    180 TEST(test_various, aaudio_state_none_open_stop) {
    181     checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
    182             AAUDIO_STREAM_STATE_OPEN,
    183             FunctionToCall::CALL_STOP,
    184             AAUDIO_OK,
    185             AAUDIO_STREAM_STATE_STOPPED);
    186 }
    187 
    188 TEST(test_various, aaudio_state_lowlat_open_pause) {
    189     checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
    190             AAUDIO_STREAM_STATE_OPEN,
    191             FunctionToCall::CALL_PAUSE,
    192             AAUDIO_OK,
    193             AAUDIO_STREAM_STATE_PAUSED);
    194 }
    195 
    196 TEST(test_various, aaudio_state_none_open_pause) {
    197     checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
    198             AAUDIO_STREAM_STATE_OPEN,
    199             FunctionToCall::CALL_PAUSE,
    200             AAUDIO_OK,
    201             AAUDIO_STREAM_STATE_PAUSED);
    202 }
    203 
    204 TEST(test_various, aaudio_state_lowlat_open_flush) {
    205     checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
    206             AAUDIO_STREAM_STATE_OPEN,
    207             FunctionToCall::CALL_FLUSH,
    208             AAUDIO_OK,
    209             AAUDIO_STREAM_STATE_FLUSHED);
    210 }
    211 
    212 TEST(test_various, aaudio_state_none_open_flush) {
    213     checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
    214             AAUDIO_STREAM_STATE_OPEN,
    215             FunctionToCall::CALL_FLUSH,
    216             AAUDIO_OK,
    217             AAUDIO_STREAM_STATE_FLUSHED);
    218 }
    219 
    220 
    221 // STARTED =================================================================
    222 TEST(test_various, aaudio_state_lowlat_started_start) {
    223     checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
    224             AAUDIO_STREAM_STATE_STARTED,
    225             FunctionToCall::CALL_START,
    226             AAUDIO_ERROR_INVALID_STATE,
    227             AAUDIO_STREAM_STATE_STARTED);
    228 }
    229 
    230 TEST(test_various, aaudio_state_none_started_start) {
    231     checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
    232             AAUDIO_STREAM_STATE_STARTED,
    233             FunctionToCall::CALL_START,
    234             AAUDIO_ERROR_INVALID_STATE,
    235             AAUDIO_STREAM_STATE_STARTED);
    236 }
    237 
    238 TEST(test_various, aaudio_state_lowlat_started_stop) {
    239     checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
    240             AAUDIO_STREAM_STATE_STARTED,
    241             FunctionToCall::CALL_STOP,
    242             AAUDIO_OK,
    243             AAUDIO_STREAM_STATE_STOPPED);
    244 }
    245 
    246 TEST(test_various, aaudio_state_none_started_stop) {
    247     checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
    248             AAUDIO_STREAM_STATE_STARTED,
    249             FunctionToCall::CALL_STOP,
    250             AAUDIO_OK,
    251             AAUDIO_STREAM_STATE_STOPPED);
    252 }
    253 
    254 TEST(test_various, aaudio_state_lowlat_started_pause) {
    255     checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
    256             AAUDIO_STREAM_STATE_STARTED,
    257             FunctionToCall::CALL_PAUSE,
    258             AAUDIO_OK,
    259             AAUDIO_STREAM_STATE_PAUSED);
    260 }
    261 
    262 TEST(test_various, aaudio_state_none_started_pause) {
    263     checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
    264             AAUDIO_STREAM_STATE_STARTED,
    265             FunctionToCall::CALL_PAUSE,
    266             AAUDIO_OK,
    267             AAUDIO_STREAM_STATE_PAUSED);
    268 }
    269 
    270 TEST(test_various, aaudio_state_lowlat_started_flush) {
    271     checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
    272             AAUDIO_STREAM_STATE_STARTED,
    273             FunctionToCall::CALL_FLUSH,
    274             AAUDIO_ERROR_INVALID_STATE,
    275             AAUDIO_STREAM_STATE_STARTED);
    276 }
    277 
    278 TEST(test_various, aaudio_state_none_started_flush) {
    279     checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
    280             AAUDIO_STREAM_STATE_STARTED,
    281             FunctionToCall::CALL_FLUSH,
    282             AAUDIO_ERROR_INVALID_STATE,
    283             AAUDIO_STREAM_STATE_STARTED);
    284 }
    285 
    286 // STOPPED =================================================================
    287 TEST(test_various, aaudio_state_lowlat_stopped_start) {
    288     checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
    289             AAUDIO_STREAM_STATE_STOPPED,
    290             FunctionToCall::CALL_START,
    291             AAUDIO_OK,
    292             AAUDIO_STREAM_STATE_STARTED);
    293 }
    294 
    295 TEST(test_various, aaudio_state_none_stopped_start) {
    296     checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
    297             AAUDIO_STREAM_STATE_STOPPED,
    298             FunctionToCall::CALL_START,
    299             AAUDIO_OK,
    300             AAUDIO_STREAM_STATE_STARTED);
    301 }
    302 
    303 TEST(test_various, aaudio_state_lowlat_stopped_stop) {
    304     checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
    305             AAUDIO_STREAM_STATE_STOPPED,
    306             FunctionToCall::CALL_STOP,
    307             AAUDIO_OK,
    308             AAUDIO_STREAM_STATE_STOPPED);
    309 }
    310 
    311 TEST(test_various, aaudio_state_none_stopped_stop) {
    312     checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
    313             AAUDIO_STREAM_STATE_STOPPED,
    314             FunctionToCall::CALL_STOP,
    315             AAUDIO_OK,
    316             AAUDIO_STREAM_STATE_STOPPED);
    317 }
    318 
    319 TEST(test_various, aaudio_state_lowlat_stopped_pause) {
    320     checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
    321             AAUDIO_STREAM_STATE_STOPPED,
    322             FunctionToCall::CALL_PAUSE,
    323             AAUDIO_OK,
    324             AAUDIO_STREAM_STATE_PAUSED);
    325 }
    326 
    327 TEST(test_various, aaudio_state_none_stopped_pause) {
    328     checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
    329             AAUDIO_STREAM_STATE_STOPPED,
    330             FunctionToCall::CALL_PAUSE,
    331             AAUDIO_OK,
    332             AAUDIO_STREAM_STATE_PAUSED);
    333 }
    334 
    335 TEST(test_various, aaudio_state_lowlat_stopped_flush) {
    336     checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
    337             AAUDIO_STREAM_STATE_STOPPED,
    338             FunctionToCall::CALL_FLUSH,
    339             AAUDIO_OK,
    340             AAUDIO_STREAM_STATE_FLUSHED);
    341 }
    342 
    343 TEST(test_various, aaudio_state_none_stopped_flush) {
    344     checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
    345             AAUDIO_STREAM_STATE_STOPPED,
    346             FunctionToCall::CALL_FLUSH,
    347             AAUDIO_OK,
    348             AAUDIO_STREAM_STATE_FLUSHED);
    349 }
    350 
    351 // PAUSED =================================================================
    352 TEST(test_various, aaudio_state_lowlat_paused_start) {
    353 checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
    354         AAUDIO_STREAM_STATE_PAUSED,
    355         FunctionToCall::CALL_START,
    356         AAUDIO_OK,
    357         AAUDIO_STREAM_STATE_STARTED);
    358 }
    359 
    360 TEST(test_various, aaudio_state_none_paused_start) {
    361 checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
    362         AAUDIO_STREAM_STATE_PAUSED,
    363         FunctionToCall::CALL_START,
    364         AAUDIO_OK,
    365         AAUDIO_STREAM_STATE_STARTED);
    366 }
    367 
    368 TEST(test_various, aaudio_state_lowlat_paused_stop) {
    369 checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
    370         AAUDIO_STREAM_STATE_PAUSED,
    371         FunctionToCall::CALL_STOP,
    372         AAUDIO_OK,
    373         AAUDIO_STREAM_STATE_STOPPED);
    374 }
    375 
    376 TEST(test_various, aaudio_state_none_paused_stop) {
    377 checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
    378         AAUDIO_STREAM_STATE_PAUSED,
    379         FunctionToCall::CALL_STOP,
    380         AAUDIO_OK,
    381         AAUDIO_STREAM_STATE_STOPPED);
    382 }
    383 
    384 TEST(test_various, aaudio_state_lowlat_paused_pause) {
    385 checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
    386         AAUDIO_STREAM_STATE_PAUSED,
    387         FunctionToCall::CALL_PAUSE,
    388         AAUDIO_OK,
    389         AAUDIO_STREAM_STATE_PAUSED);
    390 }
    391 
    392 TEST(test_various, aaudio_state_none_paused_pause) {
    393 checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
    394         AAUDIO_STREAM_STATE_PAUSED,
    395         FunctionToCall::CALL_PAUSE,
    396         AAUDIO_OK,
    397         AAUDIO_STREAM_STATE_PAUSED);
    398 }
    399 
    400 TEST(test_various, aaudio_state_lowlat_paused_flush) {
    401 checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
    402         AAUDIO_STREAM_STATE_PAUSED,
    403         FunctionToCall::CALL_FLUSH,
    404         AAUDIO_OK,
    405         AAUDIO_STREAM_STATE_FLUSHED);
    406 }
    407 
    408 TEST(test_various, aaudio_state_none_paused_flush) {
    409 checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
    410         AAUDIO_STREAM_STATE_PAUSED,
    411         FunctionToCall::CALL_FLUSH,
    412         AAUDIO_OK,
    413         AAUDIO_STREAM_STATE_FLUSHED);
    414 }
    415 
    416 // ==========================================================================
    417 TEST(test_various, aaudio_set_buffer_size) {
    418 
    419     int32_t bufferCapacity;
    420     int32_t framesPerBurst = 0;
    421     int32_t actualSize = 0;
    422 
    423     AAudioStreamBuilder *aaudioBuilder = nullptr;
    424     AAudioStream *aaudioStream = nullptr;
    425 
    426     // Use an AAudioStreamBuilder to contain requested parameters.
    427     ASSERT_EQ(AAUDIO_OK, AAudio_createStreamBuilder(&aaudioBuilder));
    428 
    429     // Request stream properties.
    430     AAudioStreamBuilder_setDataCallback(aaudioBuilder, NoopDataCallbackProc, nullptr);
    431     AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
    432 
    433     // Create an AAudioStream using the Builder.
    434     EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream));
    435 
    436     // This is the number of frames that are read in one chunk by a DMA controller
    437     // or a DSP or a mixer.
    438     framesPerBurst = AAudioStream_getFramesPerBurst(aaudioStream);
    439     bufferCapacity = AAudioStream_getBufferCapacityInFrames(aaudioStream);
    440     printf("          bufferCapacity = %d, remainder = %d\n",
    441            bufferCapacity, bufferCapacity % framesPerBurst);
    442 
    443     actualSize = AAudioStream_setBufferSizeInFrames(aaudioStream, 0);
    444     EXPECT_GT(actualSize, 0);
    445     EXPECT_LE(actualSize, bufferCapacity);
    446 
    447     actualSize = AAudioStream_setBufferSizeInFrames(aaudioStream, 2 * framesPerBurst);
    448     EXPECT_GT(actualSize, framesPerBurst);
    449     EXPECT_LE(actualSize, bufferCapacity);
    450 
    451     actualSize = AAudioStream_setBufferSizeInFrames(aaudioStream, bufferCapacity - 1);
    452     EXPECT_GT(actualSize, framesPerBurst);
    453     EXPECT_LE(actualSize, bufferCapacity);
    454 
    455     actualSize = AAudioStream_setBufferSizeInFrames(aaudioStream, bufferCapacity);
    456     EXPECT_GT(actualSize, framesPerBurst);
    457     EXPECT_LE(actualSize, bufferCapacity);
    458 
    459     actualSize = AAudioStream_setBufferSizeInFrames(aaudioStream, bufferCapacity + 1);
    460     EXPECT_GT(actualSize, framesPerBurst);
    461     EXPECT_LE(actualSize, bufferCapacity);
    462 
    463     actualSize = AAudioStream_setBufferSizeInFrames(aaudioStream, 1234567);
    464     EXPECT_GT(actualSize, framesPerBurst);
    465     EXPECT_LE(actualSize, bufferCapacity);
    466 
    467     actualSize = AAudioStream_setBufferSizeInFrames(aaudioStream, INT32_MAX);
    468     EXPECT_GT(actualSize, framesPerBurst);
    469     EXPECT_LE(actualSize, bufferCapacity);
    470 
    471     actualSize = AAudioStream_setBufferSizeInFrames(aaudioStream, INT32_MIN);
    472     EXPECT_GT(actualSize, 0);
    473     EXPECT_LE(actualSize, bufferCapacity);
    474 
    475     AAudioStream_close(aaudioStream);
    476     AAudioStreamBuilder_delete(aaudioBuilder);
    477 }
    478 
    479 // ************************************************************
    480 // Test to make sure that AAUDIO_CALLBACK_RESULT_STOP works.
    481 
    482 // Callback function that counts calls.
    483 aaudio_data_callback_result_t CallbackOnceProc(
    484         AAudioStream *stream,
    485         void *userData,
    486         void *audioData,
    487         int32_t numFrames
    488 ) {
    489     (void) stream;
    490     (void) audioData;
    491     (void) numFrames;
    492 
    493     std::atomic<int32_t> *callbackCountPtr = (std::atomic<int32_t> *)userData;
    494     (*callbackCountPtr)++;
    495 
    496     return AAUDIO_CALLBACK_RESULT_STOP;
    497 }
    498 
    499 void checkCallbackOnce(aaudio_performance_mode_t perfMode) {
    500 
    501     std::atomic<int32_t>   callbackCount{0};
    502 
    503     AAudioStreamBuilder *aaudioBuilder = nullptr;
    504     AAudioStream *aaudioStream = nullptr;
    505 
    506     // Use an AAudioStreamBuilder to contain requested parameters.
    507     ASSERT_EQ(AAUDIO_OK, AAudio_createStreamBuilder(&aaudioBuilder));
    508 
    509     // Request stream properties.
    510     AAudioStreamBuilder_setDataCallback(aaudioBuilder, CallbackOnceProc, &callbackCount);
    511     AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, perfMode);
    512 
    513     // Create an AAudioStream using the Builder.
    514     ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream));
    515     AAudioStreamBuilder_delete(aaudioBuilder);
    516 
    517     ASSERT_EQ(AAUDIO_OK, AAudioStream_requestStart(aaudioStream));
    518 
    519     sleep(1); // Give callback a chance to run many times.
    520 
    521     EXPECT_EQ(AAUDIO_OK, AAudioStream_requestStop(aaudioStream));
    522 
    523     EXPECT_EQ(1, callbackCount.load()); // should stop after first call
    524 
    525     EXPECT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream));
    526 }
    527 
    528 TEST(test_various, aaudio_callback_once_none) {
    529     checkCallbackOnce(AAUDIO_PERFORMANCE_MODE_NONE);
    530 }
    531 
    532 TEST(test_various, aaudio_callback_once_lowlat) {
    533     checkCallbackOnce(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
    534 }
    535 
    536 // ************************************************************
    537 struct WakeUpCallbackData {
    538     void wakeOther() {
    539         // signal waiting test to wake up
    540         {
    541             std::lock_guard <std::mutex> lock(mutex);
    542             finished = true;
    543         }
    544         conditionVariable.notify_one();
    545     }
    546 
    547     void waitForFinished() {
    548         std::unique_lock <std::mutex> aLock(mutex);
    549         conditionVariable.wait(aLock, [=] { return finished; });
    550     }
    551 
    552     // For signalling foreground test when callback finished
    553     std::mutex              mutex;
    554     std::condition_variable conditionVariable;
    555     bool                    finished = false;
    556 };
    557 
    558 // Test to make sure we cannot call recursively into the system from a callback.
    559 struct DangerousData : public WakeUpCallbackData {
    560     aaudio_result_t resultStart = AAUDIO_OK;
    561     aaudio_result_t resultStop = AAUDIO_OK;
    562     aaudio_result_t resultPause = AAUDIO_OK;
    563     aaudio_result_t resultFlush = AAUDIO_OK;
    564     aaudio_result_t resultClose = AAUDIO_OK;
    565 };
    566 
    567 // Callback function that tries to call back into the stream.
    568 aaudio_data_callback_result_t DangerousDataCallbackProc(
    569         AAudioStream *stream,
    570         void *userData,
    571         void *audioData,
    572         int32_t numFrames) {
    573     (void) audioData;
    574     (void) numFrames;
    575 
    576     DangerousData *data = (DangerousData *)userData;
    577     data->resultStart = AAudioStream_requestStart(stream);
    578     data->resultStop = AAudioStream_requestStop(stream);
    579     data->resultPause = AAudioStream_requestPause(stream);
    580     data->resultFlush = AAudioStream_requestFlush(stream);
    581     data->resultClose = AAudioStream_close(stream);
    582 
    583     data->wakeOther();
    584 
    585     return AAUDIO_CALLBACK_RESULT_STOP;
    586 }
    587 
    588 //int main() { // To fix Android Studio formatting when editing.
    589 void checkDangerousCallback(aaudio_performance_mode_t perfMode) {
    590     DangerousData        dangerousData;
    591     AAudioStreamBuilder *aaudioBuilder = nullptr;
    592     AAudioStream        *aaudioStream = nullptr;
    593 
    594     // Use an AAudioStreamBuilder to contain requested parameters.
    595     ASSERT_EQ(AAUDIO_OK, AAudio_createStreamBuilder(&aaudioBuilder));
    596 
    597     // Request stream properties.
    598     AAudioStreamBuilder_setDataCallback(aaudioBuilder, DangerousDataCallbackProc, &dangerousData);
    599     AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, perfMode);
    600 
    601     // Create an AAudioStream using the Builder.
    602     ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream));
    603     AAudioStreamBuilder_delete(aaudioBuilder);
    604 
    605     ASSERT_EQ(AAUDIO_OK, AAudioStream_requestStart(aaudioStream));
    606 
    607     dangerousData.waitForFinished();
    608 
    609     EXPECT_EQ(AAUDIO_OK, AAudioStream_requestStop(aaudioStream));
    610 
    611     EXPECT_EQ(AAUDIO_ERROR_INVALID_STATE, dangerousData.resultStart);
    612     EXPECT_EQ(AAUDIO_ERROR_INVALID_STATE, dangerousData.resultStop);
    613     EXPECT_EQ(AAUDIO_ERROR_INVALID_STATE, dangerousData.resultPause);
    614     EXPECT_EQ(AAUDIO_ERROR_INVALID_STATE, dangerousData.resultFlush);
    615     EXPECT_EQ(AAUDIO_ERROR_INVALID_STATE, dangerousData.resultClose);
    616 
    617     EXPECT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream));
    618 }
    619 
    620 //int main() { // To fix Android Studio formatting when editing.
    621 
    622 TEST(test_various, aaudio_callback_blockers_none) {
    623     checkDangerousCallback(AAUDIO_PERFORMANCE_MODE_NONE);
    624 }
    625 
    626 TEST(test_various, aaudio_callback_blockers_lowlat) {
    627     checkDangerousCallback(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
    628 }
    629