aaudio: test matrix of state transitions
Test transitions from OPEN, STARTED, STOPPED and PAUSED.
Test: this is a test
Change-Id: I8e9257909f5e50834652f71b14d94a13e0e62f3f
diff --git a/media/libaaudio/tests/test_various.cpp b/media/libaaudio/tests/test_various.cpp
index dc19985..4b065c9 100644
--- a/media/libaaudio/tests/test_various.cpp
+++ b/media/libaaudio/tests/test_various.cpp
@@ -26,7 +26,6 @@
#include <gtest/gtest.h>
#include <unistd.h>
-
// Callback function that does nothing.
aaudio_data_callback_result_t NoopDataCallbackProc(
AAudioStream *stream,
@@ -45,73 +44,376 @@
constexpr int64_t NANOS_PER_MILLISECOND = 1000 * 1000;
-//int foo() { // To fix Android Studio formatting when editing.
-TEST(test_various, aaudio_stop_when_open) {
+enum FunctionToCall {
+ CALL_START, CALL_STOP, CALL_PAUSE, CALL_FLUSH
+};
+
+void checkStateTransition(aaudio_performance_mode_t perfMode,
+ aaudio_stream_state_t originalState,
+ FunctionToCall functionToCall,
+ aaudio_result_t expectedResult,
+ aaudio_stream_state_t expectedState) {
AAudioStreamBuilder *aaudioBuilder = nullptr;
AAudioStream *aaudioStream = nullptr;
-// Use an AAudioStreamBuilder to contain requested parameters.
+ // Use an AAudioStreamBuilder to contain requested parameters.
ASSERT_EQ(AAUDIO_OK, AAudio_createStreamBuilder(&aaudioBuilder));
-// Request stream properties.
+ // Request stream properties.
AAudioStreamBuilder_setDataCallback(aaudioBuilder, NoopDataCallbackProc, nullptr);
- AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
+ AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, perfMode);
-// Create an AAudioStream using the Builder.
- EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream));
+ // Create an AAudioStream using the Builder.
+ ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream));
-
+ // Verify Open State
aaudio_stream_state_t state = AAUDIO_STREAM_STATE_UNKNOWN;
EXPECT_EQ(AAUDIO_OK, AAudioStream_waitForStateChange(aaudioStream,
AAUDIO_STREAM_STATE_UNKNOWN, &state,
1000 * NANOS_PER_MILLISECOND));
EXPECT_EQ(AAUDIO_STREAM_STATE_OPEN, state);
- EXPECT_EQ(AAUDIO_OK, AAudioStream_requestStop(aaudioStream));
+ // Put stream into desired state.
+ aaudio_stream_state_t inputState = AAUDIO_STREAM_STATE_UNINITIALIZED;
+ if (originalState != AAUDIO_STREAM_STATE_OPEN) {
- state = AAUDIO_STREAM_STATE_UNKNOWN;
+ ASSERT_EQ(AAUDIO_OK, AAudioStream_requestStart(aaudioStream));
+
+ if (originalState != AAUDIO_STREAM_STATE_STARTING) {
+
+ ASSERT_EQ(AAUDIO_OK, AAudioStream_waitForStateChange(aaudioStream,
+ AAUDIO_STREAM_STATE_STARTING,
+ &state,
+ 1000 * NANOS_PER_MILLISECOND));
+ ASSERT_EQ(AAUDIO_STREAM_STATE_STARTED, state);
+
+ if (originalState == AAUDIO_STREAM_STATE_STOPPING) {
+ ASSERT_EQ(AAUDIO_OK, AAudioStream_requestStop(aaudioStream));
+ } else if (originalState == AAUDIO_STREAM_STATE_STOPPED) {
+ ASSERT_EQ(AAUDIO_OK, AAudioStream_requestStop(aaudioStream));
+ inputState = AAUDIO_STREAM_STATE_STOPPING;
+ } else if (originalState == AAUDIO_STREAM_STATE_PAUSING) {
+ ASSERT_EQ(AAUDIO_OK, AAudioStream_requestPause(aaudioStream));
+ } else if (originalState == AAUDIO_STREAM_STATE_PAUSED) {
+ ASSERT_EQ(AAUDIO_OK, AAudioStream_requestPause(aaudioStream));
+ inputState = AAUDIO_STREAM_STATE_PAUSING;
+ }
+ }
+ }
+
+ // Wait until past transitional state.
+ if (inputState != AAUDIO_STREAM_STATE_UNINITIALIZED) {
+ ASSERT_EQ(AAUDIO_OK, AAudioStream_waitForStateChange(aaudioStream,
+ inputState,
+ &state,
+ 1000 * NANOS_PER_MILLISECOND));
+ ASSERT_EQ(originalState, state);
+ }
+
+ aaudio_stream_state_t transitionalState = originalState;
+ switch(functionToCall) {
+ case FunctionToCall::CALL_START:
+ EXPECT_EQ(expectedResult, AAudioStream_requestStart(aaudioStream));
+ transitionalState = AAUDIO_STREAM_STATE_STARTING;
+ break;
+ case FunctionToCall::CALL_STOP:
+ EXPECT_EQ(expectedResult, AAudioStream_requestStop(aaudioStream));
+ transitionalState = AAUDIO_STREAM_STATE_STOPPING;
+ break;
+ case FunctionToCall::CALL_PAUSE:
+ EXPECT_EQ(expectedResult, AAudioStream_requestPause(aaudioStream));
+ transitionalState = AAUDIO_STREAM_STATE_PAUSING;
+ break;
+ case FunctionToCall::CALL_FLUSH:
+ EXPECT_EQ(expectedResult, AAudioStream_requestFlush(aaudioStream));
+ transitionalState = AAUDIO_STREAM_STATE_FLUSHING;
+ break;
+ }
+
EXPECT_EQ(AAUDIO_OK, AAudioStream_waitForStateChange(aaudioStream,
- AAUDIO_STREAM_STATE_UNKNOWN, &state, 0));
- EXPECT_EQ(AAUDIO_STREAM_STATE_OPEN, state);
-
- AAudioStream_close(aaudioStream);
- AAudioStreamBuilder_delete(aaudioBuilder);
-}
-
-//int boo() { // To fix Android Studio formatting when editing.
-TEST(test_various, aaudio_flush_when_started) {
- AAudioStreamBuilder *aaudioBuilder = nullptr;
- AAudioStream *aaudioStream = nullptr;
-
-// Use an AAudioStreamBuilder to contain requested parameters.
- ASSERT_EQ(AAUDIO_OK, AAudio_createStreamBuilder(&aaudioBuilder));
-
-// Request stream properties.
- AAudioStreamBuilder_setDataCallback(aaudioBuilder, NoopDataCallbackProc, nullptr);
- AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
-
-// Create an AAudioStream using the Builder.
- EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream));
- EXPECT_EQ(AAUDIO_OK, AAudioStream_requestStart(aaudioStream));
-
- aaudio_stream_state_t state = AAUDIO_STREAM_STATE_UNKNOWN;
- EXPECT_EQ(AAUDIO_OK, AAudioStream_waitForStateChange(aaudioStream,
- AAUDIO_STREAM_STATE_STARTING, &state,
+ transitionalState,
+ &state,
1000 * NANOS_PER_MILLISECOND));
- EXPECT_EQ(AAUDIO_STREAM_STATE_STARTED, state);
-
- EXPECT_EQ(AAUDIO_ERROR_INVALID_STATE, AAudioStream_requestFlush(aaudioStream));
-
- state = AAUDIO_STREAM_STATE_UNKNOWN;
- EXPECT_EQ(AAUDIO_OK, AAudioStream_waitForStateChange(aaudioStream,
- AAUDIO_STREAM_STATE_UNKNOWN, &state, 0));
- EXPECT_EQ(AAUDIO_STREAM_STATE_STARTED, state);
+ // We should not change state when a function fails.
+ if (expectedResult != AAUDIO_OK) {
+ ASSERT_EQ(originalState, expectedState);
+ }
+ EXPECT_EQ(expectedState, state);
+ if (state != expectedState) {
+ printf("ERROR - expected %s, actual = %s\n",
+ AAudio_convertStreamStateToText(expectedState),
+ AAudio_convertStreamStateToText(state));
+ fflush(stdout);
+ }
AAudioStream_close(aaudioStream);
AAudioStreamBuilder_delete(aaudioBuilder);
}
-//int main() { // To fix Android Studio formatting when editing.
+// TODO Use parameterized tests instead of these individual specific tests.
+
+// OPEN =================================================================
+TEST(test_various, aaudio_state_lowlat_open_start) {
+ checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
+ AAUDIO_STREAM_STATE_OPEN,
+ FunctionToCall::CALL_START,
+ AAUDIO_OK,
+ AAUDIO_STREAM_STATE_STARTED);
+}
+
+TEST(test_various, aaudio_state_none_open_start) {
+ checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
+ AAUDIO_STREAM_STATE_OPEN,
+ FunctionToCall::CALL_START,
+ AAUDIO_OK,
+ AAUDIO_STREAM_STATE_STARTED);
+}
+
+TEST(test_various, aaudio_state_lowlat_open_stop) {
+ checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
+ AAUDIO_STREAM_STATE_OPEN,
+ FunctionToCall::CALL_STOP,
+ AAUDIO_OK,
+ AAUDIO_STREAM_STATE_STOPPED);
+}
+
+TEST(test_various, aaudio_state_none_open_stop) {
+ checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
+ AAUDIO_STREAM_STATE_OPEN,
+ FunctionToCall::CALL_STOP,
+ AAUDIO_OK,
+ AAUDIO_STREAM_STATE_STOPPED);
+}
+
+TEST(test_various, aaudio_state_lowlat_open_pause) {
+ checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
+ AAUDIO_STREAM_STATE_OPEN,
+ FunctionToCall::CALL_PAUSE,
+ AAUDIO_OK,
+ AAUDIO_STREAM_STATE_PAUSED);
+}
+
+TEST(test_various, aaudio_state_none_open_pause) {
+ checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
+ AAUDIO_STREAM_STATE_OPEN,
+ FunctionToCall::CALL_PAUSE,
+ AAUDIO_OK,
+ AAUDIO_STREAM_STATE_PAUSED);
+}
+
+TEST(test_various, aaudio_state_lowlat_open_flush) {
+ checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
+ AAUDIO_STREAM_STATE_OPEN,
+ FunctionToCall::CALL_FLUSH,
+ AAUDIO_OK,
+ AAUDIO_STREAM_STATE_FLUSHED);
+}
+
+TEST(test_various, aaudio_state_none_open_flush) {
+ checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
+ AAUDIO_STREAM_STATE_OPEN,
+ FunctionToCall::CALL_FLUSH,
+ AAUDIO_OK,
+ AAUDIO_STREAM_STATE_FLUSHED);
+}
+
+
+// STARTED =================================================================
+TEST(test_various, aaudio_state_lowlat_started_start) {
+ checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
+ AAUDIO_STREAM_STATE_STARTED,
+ FunctionToCall::CALL_START,
+ AAUDIO_ERROR_INVALID_STATE,
+ AAUDIO_STREAM_STATE_STARTED);
+}
+
+TEST(test_various, aaudio_state_none_started_start) {
+ checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
+ AAUDIO_STREAM_STATE_STARTED,
+ FunctionToCall::CALL_START,
+ AAUDIO_ERROR_INVALID_STATE,
+ AAUDIO_STREAM_STATE_STARTED);
+}
+
+TEST(test_various, aaudio_state_lowlat_started_stop) {
+ checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
+ AAUDIO_STREAM_STATE_STARTED,
+ FunctionToCall::CALL_STOP,
+ AAUDIO_OK,
+ AAUDIO_STREAM_STATE_STOPPED);
+}
+
+TEST(test_various, aaudio_state_none_started_stop) {
+ checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
+ AAUDIO_STREAM_STATE_STARTED,
+ FunctionToCall::CALL_STOP,
+ AAUDIO_OK,
+ AAUDIO_STREAM_STATE_STOPPED);
+}
+
+TEST(test_various, aaudio_state_lowlat_started_pause) {
+ checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
+ AAUDIO_STREAM_STATE_STARTED,
+ FunctionToCall::CALL_PAUSE,
+ AAUDIO_OK,
+ AAUDIO_STREAM_STATE_PAUSED);
+}
+
+TEST(test_various, aaudio_state_none_started_pause) {
+ checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
+ AAUDIO_STREAM_STATE_STARTED,
+ FunctionToCall::CALL_PAUSE,
+ AAUDIO_OK,
+ AAUDIO_STREAM_STATE_PAUSED);
+}
+
+TEST(test_various, aaudio_state_lowlat_started_flush) {
+ checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
+ AAUDIO_STREAM_STATE_STARTED,
+ FunctionToCall::CALL_FLUSH,
+ AAUDIO_ERROR_INVALID_STATE,
+ AAUDIO_STREAM_STATE_STARTED);
+}
+
+TEST(test_various, aaudio_state_none_started_flush) {
+ checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
+ AAUDIO_STREAM_STATE_STARTED,
+ FunctionToCall::CALL_FLUSH,
+ AAUDIO_ERROR_INVALID_STATE,
+ AAUDIO_STREAM_STATE_STARTED);
+}
+
+// STOPPED =================================================================
+TEST(test_various, aaudio_state_lowlat_stopped_start) {
+ checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
+ AAUDIO_STREAM_STATE_STOPPED,
+ FunctionToCall::CALL_START,
+ AAUDIO_OK,
+ AAUDIO_STREAM_STATE_STARTED);
+}
+
+TEST(test_various, aaudio_state_none_stopped_start) {
+ checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
+ AAUDIO_STREAM_STATE_STOPPED,
+ FunctionToCall::CALL_START,
+ AAUDIO_OK,
+ AAUDIO_STREAM_STATE_STARTED);
+}
+
+TEST(test_various, aaudio_state_lowlat_stopped_stop) {
+ checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
+ AAUDIO_STREAM_STATE_STOPPED,
+ FunctionToCall::CALL_STOP,
+ AAUDIO_OK,
+ AAUDIO_STREAM_STATE_STOPPED);
+}
+
+TEST(test_various, aaudio_state_none_stopped_stop) {
+ checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
+ AAUDIO_STREAM_STATE_STOPPED,
+ FunctionToCall::CALL_STOP,
+ AAUDIO_OK,
+ AAUDIO_STREAM_STATE_STOPPED);
+}
+
+TEST(test_various, aaudio_state_lowlat_stopped_pause) {
+ checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
+ AAUDIO_STREAM_STATE_STOPPED,
+ FunctionToCall::CALL_PAUSE,
+ AAUDIO_OK,
+ AAUDIO_STREAM_STATE_PAUSED);
+}
+
+TEST(test_various, aaudio_state_none_stopped_pause) {
+ checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
+ AAUDIO_STREAM_STATE_STOPPED,
+ FunctionToCall::CALL_PAUSE,
+ AAUDIO_OK,
+ AAUDIO_STREAM_STATE_PAUSED);
+}
+
+TEST(test_various, aaudio_state_lowlat_stopped_flush) {
+ checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
+ AAUDIO_STREAM_STATE_STOPPED,
+ FunctionToCall::CALL_FLUSH,
+ AAUDIO_OK,
+ AAUDIO_STREAM_STATE_FLUSHED);
+}
+
+TEST(test_various, aaudio_state_none_stopped_flush) {
+ checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
+ AAUDIO_STREAM_STATE_STOPPED,
+ FunctionToCall::CALL_FLUSH,
+ AAUDIO_OK,
+ AAUDIO_STREAM_STATE_FLUSHED);
+}
+
+// PAUSED =================================================================
+TEST(test_various, aaudio_state_lowlat_paused_start) {
+checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
+ AAUDIO_STREAM_STATE_PAUSED,
+ FunctionToCall::CALL_START,
+ AAUDIO_OK,
+ AAUDIO_STREAM_STATE_STARTED);
+}
+
+TEST(test_various, aaudio_state_none_paused_start) {
+checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
+ AAUDIO_STREAM_STATE_PAUSED,
+ FunctionToCall::CALL_START,
+ AAUDIO_OK,
+ AAUDIO_STREAM_STATE_STARTED);
+}
+
+TEST(test_various, aaudio_state_lowlat_paused_stop) {
+checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
+ AAUDIO_STREAM_STATE_PAUSED,
+ FunctionToCall::CALL_STOP,
+ AAUDIO_OK,
+ AAUDIO_STREAM_STATE_STOPPED);
+}
+
+TEST(test_various, aaudio_state_none_paused_stop) {
+checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
+ AAUDIO_STREAM_STATE_PAUSED,
+ FunctionToCall::CALL_STOP,
+ AAUDIO_OK,
+ AAUDIO_STREAM_STATE_STOPPED);
+}
+
+TEST(test_various, aaudio_state_lowlat_paused_pause) {
+checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
+ AAUDIO_STREAM_STATE_PAUSED,
+ FunctionToCall::CALL_PAUSE,
+ AAUDIO_OK,
+ AAUDIO_STREAM_STATE_PAUSED);
+}
+
+TEST(test_various, aaudio_state_none_paused_pause) {
+checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
+ AAUDIO_STREAM_STATE_PAUSED,
+ FunctionToCall::CALL_PAUSE,
+ AAUDIO_OK,
+ AAUDIO_STREAM_STATE_PAUSED);
+}
+
+TEST(test_various, aaudio_state_lowlat_paused_flush) {
+checkStateTransition(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY,
+ AAUDIO_STREAM_STATE_PAUSED,
+ FunctionToCall::CALL_FLUSH,
+ AAUDIO_OK,
+ AAUDIO_STREAM_STATE_FLUSHED);
+}
+
+TEST(test_various, aaudio_state_none_paused_flush) {
+checkStateTransition(AAUDIO_PERFORMANCE_MODE_NONE,
+ AAUDIO_STREAM_STATE_PAUSED,
+ FunctionToCall::CALL_FLUSH,
+ AAUDIO_OK,
+ AAUDIO_STREAM_STATE_FLUSHED);
+}
+
+// ==========================================================================
TEST(test_various, aaudio_set_buffer_size) {
int32_t bufferCapacity;
@@ -174,7 +476,6 @@
AAudioStreamBuilder_delete(aaudioBuilder);
}
-
// ************************************************************
// Test to make sure that AAUDIO_CALLBACK_RESULT_STOP works.