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 #include <thread>
29 
30 // Callback function that does nothing.
NoopDataCallbackProc(AAudioStream * stream,void *,void * audioData,int32_t numFrames)31 aaudio_data_callback_result_t NoopDataCallbackProc(
32         AAudioStream * stream,
33         void * /* userData */,
34         void *audioData,
35         int32_t numFrames
36 ) {
37     aaudio_direction_t direction = AAudioStream_getDirection(stream);
38     if (direction == AAUDIO_DIRECTION_INPUT) {
39         return AAUDIO_CALLBACK_RESULT_CONTINUE;
40     }
41     // Check to make sure the buffer is initialized to all zeros.
42     int channels = AAudioStream_getChannelCount(stream);
43     int numSamples = channels * numFrames;
44     bool allZeros = true;
45     float * const floatData = reinterpret_cast<float *>(audioData);
46     for (int i = 0; i < numSamples; i++) {
47         allZeros &= (floatData[i] == 0.0f);
48         floatData[i] = 0.0f;
49     }
50     EXPECT_TRUE(allZeros);
51     return AAUDIO_CALLBACK_RESULT_CONTINUE;
52 }
53 
54 constexpr int64_t NANOS_PER_MILLISECOND = 1000 * 1000;
55 constexpr int64_t MICROS_PER_MILLISECOND = 1000;
56 
checkReleaseThenClose(aaudio_performance_mode_t perfMode,aaudio_sharing_mode_t sharingMode,aaudio_direction_t direction=AAUDIO_DIRECTION_OUTPUT)57 void checkReleaseThenClose(aaudio_performance_mode_t perfMode,
58         aaudio_sharing_mode_t sharingMode,
59         aaudio_direction_t direction = AAUDIO_DIRECTION_OUTPUT) {
60     AAudioStreamBuilder* aaudioBuilder = nullptr;
61     AAudioStream* aaudioStream = nullptr;
62 
63     // Use an AAudioStreamBuilder to contain requested parameters.
64     ASSERT_EQ(AAUDIO_OK, AAudio_createStreamBuilder(&aaudioBuilder));
65 
66     // Request stream properties.
67     AAudioStreamBuilder_setDataCallback(aaudioBuilder,
68                                         NoopDataCallbackProc,
69                                         nullptr);
70     AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, perfMode);
71     AAudioStreamBuilder_setSharingMode(aaudioBuilder, sharingMode);
72     AAudioStreamBuilder_setDirection(aaudioBuilder, direction);
73     AAudioStreamBuilder_setFormat(aaudioBuilder, AAUDIO_FORMAT_PCM_FLOAT);
74 
75     // Create an AAudioStream using the Builder.
76     ASSERT_EQ(AAUDIO_OK,
77               AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream));
78     AAudioStreamBuilder_delete(aaudioBuilder);
79 
80     ASSERT_EQ(AAUDIO_OK, AAudioStream_requestStart(aaudioStream));
81 
82     sleep(1);
83 
84     EXPECT_EQ(AAUDIO_OK, AAudioStream_requestStop(aaudioStream));
85 
86     EXPECT_EQ(AAUDIO_OK, AAudioStream_release(aaudioStream));
87     EXPECT_EQ(AAUDIO_STREAM_STATE_CLOSING, AAudioStream_getState(aaudioStream));
88 
89     // We should be able to call this again without crashing.
90     EXPECT_EQ(AAUDIO_OK, AAudioStream_release(aaudioStream));
91     EXPECT_EQ(AAUDIO_STREAM_STATE_CLOSING, AAudioStream_getState(aaudioStream));
92 
93     // We expect these not to crash.
94     AAudioStream_setBufferSizeInFrames(aaudioStream, 0);
95     AAudioStream_setBufferSizeInFrames(aaudioStream, 99999999);
96 
97     // We should NOT be able to start or change a stream after it has been released.
98     EXPECT_EQ(AAUDIO_ERROR_INVALID_STATE, AAudioStream_requestStart(aaudioStream));
99     EXPECT_EQ(AAUDIO_STREAM_STATE_CLOSING, AAudioStream_getState(aaudioStream));
100     // Pause is only implemented for OUTPUT.
101     if (direction == AAUDIO_DIRECTION_OUTPUT) {
102         EXPECT_EQ(AAUDIO_ERROR_INVALID_STATE,
103                   AAudioStream_requestPause(aaudioStream));
104     }
105     EXPECT_EQ(AAUDIO_STREAM_STATE_CLOSING, AAudioStream_getState(aaudioStream));
106     EXPECT_EQ(AAUDIO_ERROR_INVALID_STATE, AAudioStream_requestStop(aaudioStream));
107     EXPECT_EQ(AAUDIO_STREAM_STATE_CLOSING, AAudioStream_getState(aaudioStream));
108 
109     // Does this crash?
110     EXPECT_GT(AAudioStream_getFramesRead(aaudioStream), 0);
111     EXPECT_GT(AAudioStream_getFramesWritten(aaudioStream), 0);
112     EXPECT_GT(AAudioStream_getFramesPerBurst(aaudioStream), 0);
113     EXPECT_GE(AAudioStream_getXRunCount(aaudioStream), 0);
114     EXPECT_GT(AAudioStream_getBufferCapacityInFrames(aaudioStream), 0);
115     EXPECT_GT(AAudioStream_getBufferSizeInFrames(aaudioStream), 0);
116 
117     int64_t timestampFrames = 0;
118     int64_t timestampNanos = 0;
119     aaudio_result_t result = AAudioStream_getTimestamp(aaudioStream, CLOCK_MONOTONIC,
120             &timestampFrames, &timestampNanos);
121     EXPECT_TRUE(result == AAUDIO_ERROR_INVALID_STATE || result == AAUDIO_ERROR_UNIMPLEMENTED);
122 
123     // Verify Closing State. Does this crash?
124     aaudio_stream_state_t state = AAUDIO_STREAM_STATE_UNKNOWN;
125     EXPECT_EQ(AAUDIO_OK, AAudioStream_waitForStateChange(aaudioStream,
126                                                          AAUDIO_STREAM_STATE_UNKNOWN, &state,
127                                                          500 * NANOS_PER_MILLISECOND));
128     EXPECT_EQ(AAUDIO_STREAM_STATE_CLOSING, state);
129 
130     EXPECT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream));
131 }
132 
TEST(test_various,aaudio_release_close_none_output)133 TEST(test_various, aaudio_release_close_none_output) {
134     checkReleaseThenClose(AAUDIO_PERFORMANCE_MODE_NONE,
135             AAUDIO_SHARING_MODE_SHARED,
136             AAUDIO_DIRECTION_OUTPUT);
137     // No EXCLUSIVE streams with MODE_NONE.
138 }
139 
TEST(test_various,aaudio_release_close_none_input)140 TEST(test_various, aaudio_release_close_none_input) {
141     checkReleaseThenClose(AAUDIO_PERFORMANCE_MODE_NONE,
142             AAUDIO_SHARING_MODE_SHARED,
143             AAUDIO_DIRECTION_INPUT);
144     // No EXCLUSIVE streams with MODE_NONE.
145 }
146 
TEST(test_various,aaudio_release_close_low_shared_output)147 TEST(test_various, aaudio_release_close_low_shared_output) {
148     checkReleaseThenClose(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
149             AAUDIO_SHARING_MODE_SHARED,
150             AAUDIO_DIRECTION_OUTPUT);
151 }
152 
TEST(test_various,aaudio_release_close_low_shared_input)153 TEST(test_various, aaudio_release_close_low_shared_input) {
154     checkReleaseThenClose(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
155             AAUDIO_SHARING_MODE_SHARED,
156             AAUDIO_DIRECTION_INPUT);
157 }
158 
TEST(test_various,aaudio_release_close_low_exclusive_output)159 TEST(test_various, aaudio_release_close_low_exclusive_output) {
160     checkReleaseThenClose(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
161             AAUDIO_SHARING_MODE_EXCLUSIVE,
162             AAUDIO_DIRECTION_OUTPUT);
163 }
164 
TEST(test_various,aaudio_release_close_low_exclusive_input)165 TEST(test_various, aaudio_release_close_low_exclusive_input) {
166     checkReleaseThenClose(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
167             AAUDIO_SHARING_MODE_EXCLUSIVE,
168             AAUDIO_DIRECTION_INPUT);
169 }
170 
171 enum FunctionToCall {
172     CALL_START, CALL_STOP, CALL_PAUSE, CALL_FLUSH, CALL_RELEASE
173 };
174 
checkStateTransition(aaudio_performance_mode_t perfMode,aaudio_stream_state_t originalState,FunctionToCall functionToCall,aaudio_result_t expectedResult,aaudio_stream_state_t expectedState)175 void checkStateTransition(aaudio_performance_mode_t perfMode,
176                           aaudio_stream_state_t originalState,
177                           FunctionToCall functionToCall,
178                           aaudio_result_t expectedResult,
179                           aaudio_stream_state_t expectedState) {
180     AAudioStreamBuilder *aaudioBuilder = nullptr;
181     AAudioStream *aaudioStream = nullptr;
182 
183     // Use an AAudioStreamBuilder to contain requested parameters.
184     ASSERT_EQ(AAUDIO_OK, AAudio_createStreamBuilder(&aaudioBuilder));
185 
186     // Request stream properties.
187     AAudioStreamBuilder_setDataCallback(aaudioBuilder, NoopDataCallbackProc, nullptr);
188     AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, perfMode);
189     AAudioStreamBuilder_setFormat(aaudioBuilder, AAUDIO_FORMAT_PCM_FLOAT);
190 
191     // Create an AAudioStream using the Builder.
192     ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream));
193 
194     // Verify Open State
195     aaudio_stream_state_t state = AAUDIO_STREAM_STATE_UNKNOWN;
196     EXPECT_EQ(AAUDIO_OK, AAudioStream_waitForStateChange(aaudioStream,
197                                                          AAUDIO_STREAM_STATE_UNKNOWN, &state,
198                                                          1000 * NANOS_PER_MILLISECOND));
199     EXPECT_EQ(AAUDIO_STREAM_STATE_OPEN, state);
200 
201     // Put stream into desired state.
202     aaudio_stream_state_t inputState = AAUDIO_STREAM_STATE_UNINITIALIZED;
203     if (originalState != AAUDIO_STREAM_STATE_OPEN) {
204 
205         ASSERT_EQ(AAUDIO_OK, AAudioStream_requestStart(aaudioStream));
206 
207         if (originalState != AAUDIO_STREAM_STATE_STARTING) {
208 
209             ASSERT_EQ(AAUDIO_OK, AAudioStream_waitForStateChange(aaudioStream,
210                                                                  AAUDIO_STREAM_STATE_STARTING,
211                                                                  &state,
212                                                                  1000 * NANOS_PER_MILLISECOND));
213             ASSERT_EQ(AAUDIO_STREAM_STATE_STARTED, state);
214 
215             if (originalState == AAUDIO_STREAM_STATE_STOPPING) {
216                 ASSERT_EQ(AAUDIO_OK, AAudioStream_requestStop(aaudioStream));
217             } else if (originalState == AAUDIO_STREAM_STATE_STOPPED) {
218                 ASSERT_EQ(AAUDIO_OK, AAudioStream_requestStop(aaudioStream));
219                 inputState = AAUDIO_STREAM_STATE_STOPPING;
220             } else if (originalState == AAUDIO_STREAM_STATE_PAUSING) {
221                 ASSERT_EQ(AAUDIO_OK, AAudioStream_requestPause(aaudioStream));
222             } else if (originalState == AAUDIO_STREAM_STATE_PAUSED) {
223                 ASSERT_EQ(AAUDIO_OK, AAudioStream_requestPause(aaudioStream));
224                 inputState = AAUDIO_STREAM_STATE_PAUSING;
225             } else if (originalState == AAUDIO_STREAM_STATE_FLUSHING) {
226                 ASSERT_EQ(AAUDIO_OK, AAudioStream_requestPause(aaudioStream));
227                 // We can only flush() after pause is complete.
228                 ASSERT_EQ(AAUDIO_OK, AAudioStream_waitForStateChange(aaudioStream,
229                                                                  AAUDIO_STREAM_STATE_PAUSING,
230                                                                  &state,
231                                                                  1000 * NANOS_PER_MILLISECOND));
232                 ASSERT_EQ(AAUDIO_STREAM_STATE_PAUSED, state);
233                 ASSERT_EQ(AAUDIO_OK, AAudioStream_requestFlush(aaudioStream));
234                 // That will put the stream into the FLUSHING state.
235                 // The FLUSHING state will persist until we process functionToCall.
236                 // That is because the transition to FLUSHED is caused by the callback,
237                 // or by calling write() or waitForStateChange(). But those will not
238                 // occur.
239             } else if (originalState == AAUDIO_STREAM_STATE_CLOSING) {
240                 ASSERT_EQ(AAUDIO_OK, AAudioStream_release(aaudioStream));
241             }
242         }
243     }
244 
245     // Wait until we get past the transitional state if requested.
246     if (inputState != AAUDIO_STREAM_STATE_UNINITIALIZED) {
247         ASSERT_EQ(AAUDIO_OK, AAudioStream_waitForStateChange(aaudioStream,
248                                                              inputState,
249                                                              &state,
250                                                              1000 * NANOS_PER_MILLISECOND));
251         ASSERT_EQ(originalState, state);
252     }
253 
254     aaudio_stream_state_t transitionalState = originalState;
255     switch(functionToCall) {
256         case FunctionToCall::CALL_START:
257             EXPECT_EQ(expectedResult, AAudioStream_requestStart(aaudioStream));
258             transitionalState = AAUDIO_STREAM_STATE_STARTING;
259             break;
260         case FunctionToCall::CALL_STOP:
261             EXPECT_EQ(expectedResult, AAudioStream_requestStop(aaudioStream));
262             transitionalState = AAUDIO_STREAM_STATE_STOPPING;
263             break;
264         case FunctionToCall::CALL_PAUSE:
265             EXPECT_EQ(expectedResult, AAudioStream_requestPause(aaudioStream));
266             transitionalState = AAUDIO_STREAM_STATE_PAUSING;
267             break;
268         case FunctionToCall::CALL_FLUSH:
269             EXPECT_EQ(expectedResult, AAudioStream_requestFlush(aaudioStream));
270             transitionalState = AAUDIO_STREAM_STATE_FLUSHING;
271             break;
272         case FunctionToCall::CALL_RELEASE:
273             EXPECT_EQ(expectedResult, AAudioStream_release(aaudioStream));
274             // Set to UNINITIALIZED so the waitForStateChange() below will
275             // will return immediately with the current state.
276             transitionalState = AAUDIO_STREAM_STATE_UNINITIALIZED;
277             break;
278     }
279 
280     EXPECT_EQ(AAUDIO_OK,
281             AAudioStream_waitForStateChange(aaudioStream,
282                     transitionalState,
283                     &state,
284                     1000 * NANOS_PER_MILLISECOND));
285 
286     // We should not change state when a function fails.
287     if (expectedResult != AAUDIO_OK) {
288         ASSERT_EQ(originalState, expectedState);
289     }
290     EXPECT_EQ(expectedState, state);
291     if (state != expectedState) {
292         printf("ERROR - expected %s, actual = %s\n",
293                 AAudio_convertStreamStateToText(expectedState),
294                 AAudio_convertStreamStateToText(state));
295         fflush(stdout);
296     }
297 
298     AAudioStream_close(aaudioStream);
299     AAudioStreamBuilder_delete(aaudioBuilder);
300 }
301 
302 // TODO Use parameterized tests instead of these individual specific tests.
303 
304 // OPEN =================================================================
TEST(test_various,aaudio_state_lowlat_open_start)305 TEST(test_various, aaudio_state_lowlat_open_start) {
306     checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
307             AAUDIO_STREAM_STATE_OPEN,
308             FunctionToCall::CALL_START,
309             AAUDIO_OK,
310             AAUDIO_STREAM_STATE_STARTED);
311 }
312 
TEST(test_various,aaudio_state_none_open_start)313 TEST(test_various, aaudio_state_none_open_start) {
314     checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
315             AAUDIO_STREAM_STATE_OPEN,
316             FunctionToCall::CALL_START,
317             AAUDIO_OK,
318             AAUDIO_STREAM_STATE_STARTED);
319 }
320 
TEST(test_various,aaudio_state_lowlat_open_stop)321 TEST(test_various, aaudio_state_lowlat_open_stop) {
322     checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
323             AAUDIO_STREAM_STATE_OPEN,
324             FunctionToCall::CALL_STOP,
325             AAUDIO_OK,
326             AAUDIO_STREAM_STATE_STOPPED);
327 }
328 
TEST(test_various,aaudio_state_none_open_stop)329 TEST(test_various, aaudio_state_none_open_stop) {
330     checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
331             AAUDIO_STREAM_STATE_OPEN,
332             FunctionToCall::CALL_STOP,
333             AAUDIO_OK,
334             AAUDIO_STREAM_STATE_STOPPED);
335 }
336 
TEST(test_various,aaudio_state_lowlat_open_pause)337 TEST(test_various, aaudio_state_lowlat_open_pause) {
338     checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
339             AAUDIO_STREAM_STATE_OPEN,
340             FunctionToCall::CALL_PAUSE,
341             AAUDIO_OK,
342             AAUDIO_STREAM_STATE_PAUSED);
343 }
344 
TEST(test_various,aaudio_state_none_open_pause)345 TEST(test_various, aaudio_state_none_open_pause) {
346     checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
347             AAUDIO_STREAM_STATE_OPEN,
348             FunctionToCall::CALL_PAUSE,
349             AAUDIO_OK,
350             AAUDIO_STREAM_STATE_PAUSED);
351 }
352 
TEST(test_various,aaudio_state_lowlat_open_flush)353 TEST(test_various, aaudio_state_lowlat_open_flush) {
354     checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
355             AAUDIO_STREAM_STATE_OPEN,
356             FunctionToCall::CALL_FLUSH,
357             AAUDIO_OK,
358             AAUDIO_STREAM_STATE_FLUSHED);
359 }
360 
TEST(test_various,aaudio_state_none_open_flush)361 TEST(test_various, aaudio_state_none_open_flush) {
362     checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
363             AAUDIO_STREAM_STATE_OPEN,
364             FunctionToCall::CALL_FLUSH,
365             AAUDIO_OK,
366             AAUDIO_STREAM_STATE_FLUSHED);
367 }
368 
369 
370 // STARTED =================================================================
TEST(test_various,aaudio_state_lowlat_started_start)371 TEST(test_various, aaudio_state_lowlat_started_start) {
372     checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
373             AAUDIO_STREAM_STATE_STARTED,
374             FunctionToCall::CALL_START,
375             AAUDIO_ERROR_INVALID_STATE,
376             AAUDIO_STREAM_STATE_STARTED);
377 }
378 
TEST(test_various,aaudio_state_none_started_start)379 TEST(test_various, aaudio_state_none_started_start) {
380     checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
381             AAUDIO_STREAM_STATE_STARTED,
382             FunctionToCall::CALL_START,
383             AAUDIO_ERROR_INVALID_STATE,
384             AAUDIO_STREAM_STATE_STARTED);
385 }
386 
TEST(test_various,aaudio_state_lowlat_started_stop)387 TEST(test_various, aaudio_state_lowlat_started_stop) {
388     checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
389             AAUDIO_STREAM_STATE_STARTED,
390             FunctionToCall::CALL_STOP,
391             AAUDIO_OK,
392             AAUDIO_STREAM_STATE_STOPPED);
393 }
394 
TEST(test_various,aaudio_state_none_started_stop)395 TEST(test_various, aaudio_state_none_started_stop) {
396     checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
397             AAUDIO_STREAM_STATE_STARTED,
398             FunctionToCall::CALL_STOP,
399             AAUDIO_OK,
400             AAUDIO_STREAM_STATE_STOPPED);
401 }
402 
TEST(test_various,aaudio_state_lowlat_started_pause)403 TEST(test_various, aaudio_state_lowlat_started_pause) {
404     checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
405             AAUDIO_STREAM_STATE_STARTED,
406             FunctionToCall::CALL_PAUSE,
407             AAUDIO_OK,
408             AAUDIO_STREAM_STATE_PAUSED);
409 }
410 
TEST(test_various,aaudio_state_none_started_pause)411 TEST(test_various, aaudio_state_none_started_pause) {
412     checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
413             AAUDIO_STREAM_STATE_STARTED,
414             FunctionToCall::CALL_PAUSE,
415             AAUDIO_OK,
416             AAUDIO_STREAM_STATE_PAUSED);
417 }
418 
TEST(test_various,aaudio_state_lowlat_started_flush)419 TEST(test_various, aaudio_state_lowlat_started_flush) {
420     checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
421             AAUDIO_STREAM_STATE_STARTED,
422             FunctionToCall::CALL_FLUSH,
423             AAUDIO_ERROR_INVALID_STATE,
424             AAUDIO_STREAM_STATE_STARTED);
425 }
426 
TEST(test_various,aaudio_state_none_started_flush)427 TEST(test_various, aaudio_state_none_started_flush) {
428     checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
429             AAUDIO_STREAM_STATE_STARTED,
430             FunctionToCall::CALL_FLUSH,
431             AAUDIO_ERROR_INVALID_STATE,
432             AAUDIO_STREAM_STATE_STARTED);
433 }
434 
435 // STOPPED =================================================================
TEST(test_various,aaudio_state_lowlat_stopped_start)436 TEST(test_various, aaudio_state_lowlat_stopped_start) {
437     checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
438             AAUDIO_STREAM_STATE_STOPPED,
439             FunctionToCall::CALL_START,
440             AAUDIO_OK,
441             AAUDIO_STREAM_STATE_STARTED);
442 }
443 
TEST(test_various,aaudio_state_none_stopped_start)444 TEST(test_various, aaudio_state_none_stopped_start) {
445     checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
446             AAUDIO_STREAM_STATE_STOPPED,
447             FunctionToCall::CALL_START,
448             AAUDIO_OK,
449             AAUDIO_STREAM_STATE_STARTED);
450 }
451 
TEST(test_various,aaudio_state_lowlat_stopped_stop)452 TEST(test_various, aaudio_state_lowlat_stopped_stop) {
453     checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
454             AAUDIO_STREAM_STATE_STOPPED,
455             FunctionToCall::CALL_STOP,
456             AAUDIO_OK,
457             AAUDIO_STREAM_STATE_STOPPED);
458 }
459 
TEST(test_various,aaudio_state_none_stopped_stop)460 TEST(test_various, aaudio_state_none_stopped_stop) {
461     checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
462             AAUDIO_STREAM_STATE_STOPPED,
463             FunctionToCall::CALL_STOP,
464             AAUDIO_OK,
465             AAUDIO_STREAM_STATE_STOPPED);
466 }
467 
TEST(test_various,aaudio_state_lowlat_stopped_pause)468 TEST(test_various, aaudio_state_lowlat_stopped_pause) {
469     checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
470             AAUDIO_STREAM_STATE_STOPPED,
471             FunctionToCall::CALL_PAUSE,
472             AAUDIO_OK,
473             AAUDIO_STREAM_STATE_PAUSED);
474 }
475 
TEST(test_various,aaudio_state_none_stopped_pause)476 TEST(test_various, aaudio_state_none_stopped_pause) {
477     checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
478             AAUDIO_STREAM_STATE_STOPPED,
479             FunctionToCall::CALL_PAUSE,
480             AAUDIO_OK,
481             AAUDIO_STREAM_STATE_PAUSED);
482 }
483 
TEST(test_various,aaudio_state_lowlat_stopped_flush)484 TEST(test_various, aaudio_state_lowlat_stopped_flush) {
485     checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
486             AAUDIO_STREAM_STATE_STOPPED,
487             FunctionToCall::CALL_FLUSH,
488             AAUDIO_OK,
489             AAUDIO_STREAM_STATE_FLUSHED);
490 }
491 
TEST(test_various,aaudio_state_none_stopped_flush)492 TEST(test_various, aaudio_state_none_stopped_flush) {
493     checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
494             AAUDIO_STREAM_STATE_STOPPED,
495             FunctionToCall::CALL_FLUSH,
496             AAUDIO_OK,
497             AAUDIO_STREAM_STATE_FLUSHED);
498 }
499 
500 // PAUSED =================================================================
TEST(test_various,aaudio_state_lowlat_paused_start)501 TEST(test_various, aaudio_state_lowlat_paused_start) {
502 checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
503         AAUDIO_STREAM_STATE_PAUSED,
504         FunctionToCall::CALL_START,
505         AAUDIO_OK,
506         AAUDIO_STREAM_STATE_STARTED);
507 }
508 
TEST(test_various,aaudio_state_none_paused_start)509 TEST(test_various, aaudio_state_none_paused_start) {
510 checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
511         AAUDIO_STREAM_STATE_PAUSED,
512         FunctionToCall::CALL_START,
513         AAUDIO_OK,
514         AAUDIO_STREAM_STATE_STARTED);
515 }
516 
TEST(test_various,aaudio_state_lowlat_paused_stop)517 TEST(test_various, aaudio_state_lowlat_paused_stop) {
518 checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
519         AAUDIO_STREAM_STATE_PAUSED,
520         FunctionToCall::CALL_STOP,
521         AAUDIO_OK,
522         AAUDIO_STREAM_STATE_STOPPED);
523 }
524 
TEST(test_various,aaudio_state_none_paused_stop)525 TEST(test_various, aaudio_state_none_paused_stop) {
526 checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
527         AAUDIO_STREAM_STATE_PAUSED,
528         FunctionToCall::CALL_STOP,
529         AAUDIO_OK,
530         AAUDIO_STREAM_STATE_STOPPED);
531 }
532 
TEST(test_various,aaudio_state_lowlat_paused_pause)533 TEST(test_various, aaudio_state_lowlat_paused_pause) {
534 checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
535         AAUDIO_STREAM_STATE_PAUSED,
536         FunctionToCall::CALL_PAUSE,
537         AAUDIO_OK,
538         AAUDIO_STREAM_STATE_PAUSED);
539 }
540 
TEST(test_various,aaudio_state_none_paused_pause)541 TEST(test_various, aaudio_state_none_paused_pause) {
542 checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
543         AAUDIO_STREAM_STATE_PAUSED,
544         FunctionToCall::CALL_PAUSE,
545         AAUDIO_OK,
546         AAUDIO_STREAM_STATE_PAUSED);
547 }
548 
TEST(test_various,aaudio_state_lowlat_paused_flush)549 TEST(test_various, aaudio_state_lowlat_paused_flush) {
550 checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
551         AAUDIO_STREAM_STATE_PAUSED,
552         FunctionToCall::CALL_FLUSH,
553         AAUDIO_OK,
554         AAUDIO_STREAM_STATE_FLUSHED);
555 }
556 
TEST(test_various,aaudio_state_none_paused_flush)557 TEST(test_various, aaudio_state_none_paused_flush) {
558 checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
559         AAUDIO_STREAM_STATE_PAUSED,
560         FunctionToCall::CALL_FLUSH,
561         AAUDIO_OK,
562         AAUDIO_STREAM_STATE_FLUSHED);
563 }
564 
565 // FLUSHING ================================================================
TEST(test_various,aaudio_state_lowlat_flushing_start)566 TEST(test_various, aaudio_state_lowlat_flushing_start) {
567 checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
568         AAUDIO_STREAM_STATE_FLUSHING,
569         FunctionToCall::CALL_START,
570         AAUDIO_OK,
571         AAUDIO_STREAM_STATE_STARTED);
572 }
573 
TEST(test_various,aaudio_state_none_flushing_start)574 TEST(test_various, aaudio_state_none_flushing_start) {
575 checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
576         AAUDIO_STREAM_STATE_FLUSHING,
577         FunctionToCall::CALL_START,
578         AAUDIO_OK,
579         AAUDIO_STREAM_STATE_STARTED);
580 }
581 
TEST(test_various,aaudio_state_lowlat_flushing_release)582 TEST(test_various, aaudio_state_lowlat_flushing_release) {
583 checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
584         AAUDIO_STREAM_STATE_FLUSHING,
585         FunctionToCall::CALL_RELEASE,
586         AAUDIO_OK,
587         AAUDIO_STREAM_STATE_CLOSING);
588 }
589 
TEST(test_various,aaudio_state_none_flushing_release)590 TEST(test_various, aaudio_state_none_flushing_release) {
591 checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
592         AAUDIO_STREAM_STATE_FLUSHING,
593         FunctionToCall::CALL_RELEASE,
594         AAUDIO_OK,
595         AAUDIO_STREAM_STATE_CLOSING);
596 }
597 
TEST(test_various,aaudio_state_lowlat_starting_release)598 TEST(test_various, aaudio_state_lowlat_starting_release) {
599 checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
600         AAUDIO_STREAM_STATE_STARTING,
601         FunctionToCall::CALL_RELEASE,
602         AAUDIO_OK,
603         AAUDIO_STREAM_STATE_CLOSING);
604 }
605 
TEST(test_various,aaudio_state_none_starting_release)606 TEST(test_various, aaudio_state_none_starting_release) {
607 checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
608         AAUDIO_STREAM_STATE_STARTING,
609         FunctionToCall::CALL_RELEASE,
610         AAUDIO_OK,
611         AAUDIO_STREAM_STATE_CLOSING);
612 }
613 
614 // CLOSING ================================================================
TEST(test_various,aaudio_state_lowlat_closing_start)615 TEST(test_various, aaudio_state_lowlat_closing_start) {
616 checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
617         AAUDIO_STREAM_STATE_CLOSING,
618         FunctionToCall::CALL_START,
619         AAUDIO_ERROR_INVALID_STATE,
620         AAUDIO_STREAM_STATE_CLOSING);
621 }
622 
TEST(test_various,aaudio_state_none_closing_start)623 TEST(test_various, aaudio_state_none_closing_start) {
624 checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
625         AAUDIO_STREAM_STATE_CLOSING,
626         FunctionToCall::CALL_START,
627         AAUDIO_ERROR_INVALID_STATE,
628         AAUDIO_STREAM_STATE_CLOSING);
629 }
630 
TEST(test_various,aaudio_state_lowlat_closing_stop)631 TEST(test_various, aaudio_state_lowlat_closing_stop) {
632 checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
633         AAUDIO_STREAM_STATE_CLOSING,
634         FunctionToCall::CALL_STOP,
635         AAUDIO_ERROR_INVALID_STATE,
636         AAUDIO_STREAM_STATE_CLOSING);
637 }
638 
TEST(test_various,aaudio_state_none_closing_stop)639 TEST(test_various, aaudio_state_none_closing_stop) {
640 checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
641         AAUDIO_STREAM_STATE_CLOSING,
642         FunctionToCall::CALL_STOP,
643         AAUDIO_ERROR_INVALID_STATE,
644         AAUDIO_STREAM_STATE_CLOSING);
645 }
646 
647 // ==========================================================================
TEST(test_various,aaudio_set_buffer_size)648 TEST(test_various, aaudio_set_buffer_size) {
649 
650     int32_t bufferCapacity;
651     int32_t framesPerBurst = 0;
652     int32_t actualSize = 0;
653 
654     AAudioStreamBuilder *aaudioBuilder = nullptr;
655     AAudioStream *aaudioStream = nullptr;
656 
657     // Use an AAudioStreamBuilder to contain requested parameters.
658     ASSERT_EQ(AAUDIO_OK, AAudio_createStreamBuilder(&aaudioBuilder));
659 
660     // Request stream properties.
661     AAudioStreamBuilder_setDataCallback(aaudioBuilder, NoopDataCallbackProc, nullptr);
662     AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
663 
664     // Create an AAudioStream using the Builder.
665     EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream));
666 
667     // This is the number of frames that are read in one chunk by a DMA controller
668     // or a DSP or a mixer.
669     framesPerBurst = AAudioStream_getFramesPerBurst(aaudioStream);
670     bufferCapacity = AAudioStream_getBufferCapacityInFrames(aaudioStream);
671     printf("          bufferCapacity = %d, remainder = %d\n",
672            bufferCapacity, bufferCapacity % framesPerBurst);
673 
674     actualSize = AAudioStream_setBufferSizeInFrames(aaudioStream, 0);
675     EXPECT_GE(actualSize, 0); // 0 is legal in R
676     EXPECT_LE(actualSize, bufferCapacity);
677 
678     actualSize = AAudioStream_setBufferSizeInFrames(aaudioStream, 2 * framesPerBurst);
679     EXPECT_GT(actualSize, framesPerBurst);
680     EXPECT_LE(actualSize, bufferCapacity);
681 
682     actualSize = AAudioStream_setBufferSizeInFrames(aaudioStream, bufferCapacity - 1);
683     EXPECT_GT(actualSize, framesPerBurst);
684     EXPECT_LE(actualSize, bufferCapacity);
685 
686     actualSize = AAudioStream_setBufferSizeInFrames(aaudioStream, bufferCapacity);
687     EXPECT_GT(actualSize, framesPerBurst);
688     EXPECT_LE(actualSize, bufferCapacity);
689 
690     actualSize = AAudioStream_setBufferSizeInFrames(aaudioStream, bufferCapacity + 1);
691     EXPECT_GT(actualSize, framesPerBurst);
692     EXPECT_LE(actualSize, bufferCapacity);
693 
694     actualSize = AAudioStream_setBufferSizeInFrames(aaudioStream, 1234567);
695     EXPECT_GT(actualSize, framesPerBurst);
696     EXPECT_LE(actualSize, bufferCapacity);
697 
698     actualSize = AAudioStream_setBufferSizeInFrames(aaudioStream, INT32_MAX);
699     EXPECT_GT(actualSize, framesPerBurst);
700     EXPECT_LE(actualSize, bufferCapacity);
701 
702     actualSize = AAudioStream_setBufferSizeInFrames(aaudioStream, INT32_MIN);
703     EXPECT_GE(actualSize, 0); // 0 is legal in R
704     EXPECT_LE(actualSize, bufferCapacity);
705 
706     AAudioStream_close(aaudioStream);
707     AAudioStreamBuilder_delete(aaudioBuilder);
708 }
709 
710 // ************************************************************
711 // Test to make sure that AAUDIO_CALLBACK_RESULT_STOP works.
712 
713 // Callback function that counts calls.
CallbackOnceProc(AAudioStream * stream,void * userData,void * audioData,int32_t numFrames)714 aaudio_data_callback_result_t CallbackOnceProc(
715         AAudioStream *stream,
716         void *userData,
717         void *audioData,
718         int32_t numFrames
719 ) {
720     (void) stream;
721     (void) audioData;
722     (void) numFrames;
723 
724     std::atomic<int32_t> *callbackCountPtr = (std::atomic<int32_t> *)userData;
725     (*callbackCountPtr)++;
726 
727     return AAUDIO_CALLBACK_RESULT_STOP;
728 }
729 
checkCallbackOnce(aaudio_performance_mode_t perfMode)730 void checkCallbackOnce(aaudio_performance_mode_t perfMode) {
731 
732     std::atomic<int32_t>   callbackCount{0};
733 
734     AAudioStreamBuilder *aaudioBuilder = nullptr;
735     AAudioStream *aaudioStream = nullptr;
736 
737     // Use an AAudioStreamBuilder to contain requested parameters.
738     ASSERT_EQ(AAUDIO_OK, AAudio_createStreamBuilder(&aaudioBuilder));
739 
740     // Request stream properties.
741     AAudioStreamBuilder_setDataCallback(aaudioBuilder, CallbackOnceProc, &callbackCount);
742     AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, perfMode);
743 
744     // Create an AAudioStream using the Builder.
745     ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream));
746     AAudioStreamBuilder_delete(aaudioBuilder);
747 
748     ASSERT_EQ(AAUDIO_OK, AAudioStream_requestStart(aaudioStream));
749 
750     sleep(1); // Give callback a chance to run many times.
751 
752     EXPECT_EQ(AAUDIO_OK, AAudioStream_requestStop(aaudioStream));
753 
754     EXPECT_EQ(1, callbackCount.load()); // should stop after first call
755 
756     EXPECT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream));
757 }
758 
TEST(test_various,aaudio_callback_once_none)759 TEST(test_various, aaudio_callback_once_none) {
760     checkCallbackOnce(AAUDIO_PERFORMANCE_MODE_NONE);
761 }
762 
TEST(test_various,aaudio_callback_once_lowlat)763 TEST(test_various, aaudio_callback_once_lowlat) {
764     checkCallbackOnce(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
765 }
766 
waitForStateChangeToClosingorClosed(AAudioStream ** stream,std::atomic<bool> * isReady)767 void waitForStateChangeToClosingorClosed(AAudioStream **stream, std::atomic<bool>* isReady)
768 {
769     *isReady = true;
770     aaudio_stream_state_t state = AAUDIO_STREAM_STATE_UNKNOWN;
771     EXPECT_EQ(AAUDIO_OK, AAudioStream_waitForStateChange(*stream,
772                                                          AAUDIO_STREAM_STATE_OPEN, &state,
773                                                          10000 * NANOS_PER_MILLISECOND));
774     if ((state != AAUDIO_STREAM_STATE_CLOSING) && (state != AAUDIO_STREAM_STATE_CLOSED)){
775         FAIL() << "ERROR - State not closing or closed. Current state: " <<
776                 AAudio_convertStreamStateToText(state);
777     }
778 }
779 
testWaitForStateChangeClose(aaudio_performance_mode_t perfMode)780 void testWaitForStateChangeClose(aaudio_performance_mode_t perfMode) {
781     AAudioStreamBuilder *aaudioBuilder = nullptr;
782     AAudioStream *aaudioStream = nullptr;
783 
784     ASSERT_EQ(AAUDIO_OK, AAudio_createStreamBuilder(&aaudioBuilder));
785     AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, perfMode);
786     ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream));
787 
788     // Verify Open State
789     aaudio_stream_state_t state = AAUDIO_STREAM_STATE_UNKNOWN;
790     EXPECT_EQ(AAUDIO_OK, AAudioStream_waitForStateChange(aaudioStream,
791                                                          AAUDIO_STREAM_STATE_UNKNOWN, &state,
792                                                          1000 * NANOS_PER_MILLISECOND));
793     EXPECT_EQ(AAUDIO_STREAM_STATE_OPEN, state);
794 
795     std::atomic<bool> isWaitThreadReady{false};
796 
797     // Spawn a new thread to wait for the state change
798     std::thread waitThread (waitForStateChangeToClosingorClosed, &aaudioStream,
799                             &isWaitThreadReady);
800 
801     // Wait for worker thread to be ready
802     while (!isWaitThreadReady) {
803         usleep(MICROS_PER_MILLISECOND);
804     }
805     // Sleep an additional millisecond to make sure waitForAudioThread is called
806     usleep(MICROS_PER_MILLISECOND);
807     EXPECT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream));
808     waitThread.join();
809 }
810 
TEST(test_various,wait_for_state_change_close_none)811 TEST(test_various, wait_for_state_change_close_none) {
812     testWaitForStateChangeClose(AAUDIO_PERFORMANCE_MODE_NONE);
813 }
814 
TEST(test_various,wait_for_state_change_close_lowlat)815 TEST(test_various, wait_for_state_change_close_lowlat) {
816     testWaitForStateChangeClose(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
817 }
818 
819 // ************************************************************
820 struct WakeUpCallbackData {
wakeOtherWakeUpCallbackData821     void wakeOther() {
822         // signal waiting test to wake up
823         {
824             std::lock_guard <std::mutex> lock(mutex);
825             finished = true;
826         }
827         conditionVariable.notify_one();
828     }
829 
waitForFinishedWakeUpCallbackData830     void waitForFinished() {
831         std::unique_lock <std::mutex> aLock(mutex);
832         conditionVariable.wait(aLock, [this] { return finished; });
833     }
834 
835     // For signalling foreground test when callback finished
836     std::mutex              mutex;
837     std::condition_variable conditionVariable;
838     bool                    finished = false;
839 };
840 
841 // Test to make sure we cannot call recursively into the system from a callback.
842 struct DangerousData : public WakeUpCallbackData {
843     aaudio_result_t resultStart = AAUDIO_OK;
844     aaudio_result_t resultStop = AAUDIO_OK;
845     aaudio_result_t resultPause = AAUDIO_OK;
846     aaudio_result_t resultFlush = AAUDIO_OK;
847     aaudio_result_t resultClose = AAUDIO_OK;
848 };
849 
850 // Callback function that tries to call back into the stream.
DangerousDataCallbackProc(AAudioStream * stream,void * userData,void * audioData,int32_t numFrames)851 aaudio_data_callback_result_t DangerousDataCallbackProc(
852         AAudioStream *stream,
853         void *userData,
854         void *audioData,
855         int32_t numFrames) {
856     (void) audioData;
857     (void) numFrames;
858 
859     DangerousData *data = (DangerousData *)userData;
860     data->resultStart = AAudioStream_requestStart(stream);
861     data->resultStop = AAudioStream_requestStop(stream);
862     data->resultPause = AAudioStream_requestPause(stream);
863     data->resultFlush = AAudioStream_requestFlush(stream);
864     data->resultClose = AAudioStream_close(stream);
865 
866     data->wakeOther();
867 
868     return AAUDIO_CALLBACK_RESULT_STOP;
869 }
870 
871 //int main() { // To fix Android Studio formatting when editing.
checkDangerousCallback(aaudio_performance_mode_t perfMode)872 void checkDangerousCallback(aaudio_performance_mode_t perfMode) {
873     DangerousData        dangerousData;
874     AAudioStreamBuilder *aaudioBuilder = nullptr;
875     AAudioStream        *aaudioStream = nullptr;
876 
877     // Use an AAudioStreamBuilder to contain requested parameters.
878     ASSERT_EQ(AAUDIO_OK, AAudio_createStreamBuilder(&aaudioBuilder));
879 
880     // Request stream properties.
881     AAudioStreamBuilder_setDataCallback(aaudioBuilder, DangerousDataCallbackProc, &dangerousData);
882     AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, perfMode);
883 
884     // Create an AAudioStream using the Builder.
885     ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream));
886     AAudioStreamBuilder_delete(aaudioBuilder);
887 
888     ASSERT_EQ(AAUDIO_OK, AAudioStream_requestStart(aaudioStream));
889 
890     dangerousData.waitForFinished();
891 
892     EXPECT_EQ(AAUDIO_OK, AAudioStream_requestStop(aaudioStream));
893 
894     EXPECT_EQ(AAUDIO_ERROR_INVALID_STATE, dangerousData.resultStart);
895     EXPECT_EQ(AAUDIO_ERROR_INVALID_STATE, dangerousData.resultStop);
896     EXPECT_EQ(AAUDIO_ERROR_INVALID_STATE, dangerousData.resultPause);
897     EXPECT_EQ(AAUDIO_ERROR_INVALID_STATE, dangerousData.resultFlush);
898     EXPECT_EQ(AAUDIO_ERROR_INVALID_STATE, dangerousData.resultClose);
899 
900     EXPECT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream));
901 }
902 
903 //int main() { // To fix Android Studio formatting when editing.
904 
TEST(test_various,aaudio_callback_blockers_none)905 TEST(test_various, aaudio_callback_blockers_none) {
906     checkDangerousCallback(AAUDIO_PERFORMANCE_MODE_NONE);
907 }
908 
TEST(test_various,aaudio_callback_blockers_lowlat)909 TEST(test_various, aaudio_callback_blockers_lowlat) {
910     checkDangerousCallback(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
911 }
912