diff options
Diffstat (limited to 'externals/oboe/tests/testStreamWaitState.cpp')
| -rw-r--r-- | externals/oboe/tests/testStreamWaitState.cpp | 251 |
1 files changed, 251 insertions, 0 deletions
diff --git a/externals/oboe/tests/testStreamWaitState.cpp b/externals/oboe/tests/testStreamWaitState.cpp new file mode 100644 index 0000000000..bdf3a2f8a6 --- /dev/null +++ b/externals/oboe/tests/testStreamWaitState.cpp @@ -0,0 +1,251 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <thread> + +#include <gtest/gtest.h> + +#include <oboe/Oboe.h> + +using namespace oboe; + +class TestStreamWaitState : public ::testing::Test { + +protected: + + void SetUp(){ + mBuilder.setPerformanceMode(PerformanceMode::None); + mBuilder.setDirection(Direction::Output); + } + + bool openStream(Direction direction, PerformanceMode perfMode) { + mBuilder.setDirection(direction); + mBuilder.setPerformanceMode(perfMode); + Result r = mBuilder.openStream(mStream); + EXPECT_EQ(r, Result::OK) << "Failed to open stream " << convertToText(r); + if (r != Result::OK) + return false; + + Direction d = mStream->getDirection(); + EXPECT_EQ(d, direction) << convertToText(mStream->getDirection()); + return (d == direction); + } + + bool openStream(AudioStreamBuilder &builder) { + Result r = builder.openStream(mStream); + EXPECT_EQ(r, Result::OK) << "Failed to open stream " << convertToText(r); + return (r == Result::OK); + } + + bool closeStream() { + Result r = mStream->close(); + EXPECT_TRUE(r == Result::OK || r == Result::ErrorClosed) << + "Failed to close stream. " << convertToText(r); + return (r == Result::OK || r == Result::ErrorClosed); + } + + // if zero then don't wait for a state change + void checkWaitForStateChangeTimeout(int64_t timeout = kTimeoutInNanos) { + StreamState next = StreamState::Unknown; + Result result = mStream->waitForStateChange(mStream->getState(), &next, timeout); + EXPECT_EQ(Result::ErrorTimeout, result); + } + + void checkStopWhileWaiting() { + StreamState next = StreamState::Unknown; + auto r = mStream->requestStart(); + EXPECT_EQ(r, Result::OK); + r = mStream->waitForStateChange(StreamState::Starting, &next, kTimeoutInNanos); + EXPECT_EQ(r, Result::OK); + EXPECT_EQ(next, StreamState::Started) << "next = " << convertToText(next); + + std::shared_ptr<AudioStream> str = mStream; + + std::thread stopper([str] { + usleep(200 * 1000); + str->requestStop(); + }); + + r = mStream->waitForStateChange(StreamState::Started, &next, 1000 * kNanosPerMillisecond); + stopper.join(); + EXPECT_EQ(r, Result::OK); + // May have caught in stopping transition. Wait for full stop. + if (next == StreamState::Stopping) { + r = mStream->waitForStateChange(StreamState::Stopping, &next, 1000 * kNanosPerMillisecond); + EXPECT_EQ(r, Result::OK); + } + ASSERT_EQ(next, StreamState::Stopped) << "next = " << convertToText(next); + } + + void checkCloseWhileWaiting() { + StreamState next = StreamState::Unknown; + auto r = mStream->requestStart(); + EXPECT_EQ(r, Result::OK); + r = mStream->waitForStateChange(StreamState::Starting, &next, kTimeoutInNanos); + EXPECT_EQ(r, Result::OK); + EXPECT_EQ(next, StreamState::Started) << "next = " << convertToText(next); + + std::shared_ptr<AudioStream> str = mStream; + + std::thread closer([str] { + usleep(200 * 1000); + str->close(); + }); + + r = mStream->waitForStateChange(StreamState::Started, &next, 1000 * kNanosPerMillisecond); + closer.join(); + // You might catch this at any point in stopping or closing. + EXPECT_TRUE(r == Result::OK || r == Result::ErrorClosed) << "r = " << convertToText(r); + ASSERT_TRUE(next == StreamState::Stopping + || next == StreamState::Stopped + || next == StreamState::Pausing + || next == StreamState::Paused + || next == StreamState::Closed) << "next = " << convertToText(next); + } + + AudioStreamBuilder mBuilder; + std::shared_ptr<AudioStream> mStream; + static constexpr int kTimeoutInNanos = 100 * kNanosPerMillisecond; + +}; + +// Test return of error timeout when zero passed as the timeoutNanos. +TEST_F(TestStreamWaitState, OutputLowWaitZero) { + ASSERT_TRUE(openStream(Direction::Output, PerformanceMode::LowLatency)); + checkWaitForStateChangeTimeout(0); + ASSERT_TRUE(closeStream()); +} + +TEST_F(TestStreamWaitState, OutputNoneWaitZero) { + ASSERT_TRUE(openStream(Direction::Output, PerformanceMode::None)); + checkWaitForStateChangeTimeout(0); + ASSERT_TRUE(closeStream()); +} + +TEST_F(TestStreamWaitState, OutputLowWaitZeroSLES) { + AudioStreamBuilder builder; + builder.setPerformanceMode(PerformanceMode::LowLatency); + builder.setAudioApi(AudioApi::OpenSLES); + ASSERT_TRUE(openStream(builder)); + checkWaitForStateChangeTimeout(0); + ASSERT_TRUE(closeStream()); +} + +TEST_F(TestStreamWaitState, OutputNoneWaitZeroSLES) { + AudioStreamBuilder builder; + builder.setPerformanceMode(PerformanceMode::None); + builder.setAudioApi(AudioApi::OpenSLES); + ASSERT_TRUE(openStream(builder)); + checkWaitForStateChangeTimeout(0); + ASSERT_TRUE(closeStream()); +} + +// Test actual timeout. +TEST_F(TestStreamWaitState, OutputLowWaitNonZero) { + ASSERT_TRUE(openStream(Direction::Output, PerformanceMode::LowLatency)); + checkWaitForStateChangeTimeout(); + ASSERT_TRUE(closeStream()); +} + +TEST_F(TestStreamWaitState, OutputNoneWaitNonZero) { + ASSERT_TRUE(openStream(Direction::Output, PerformanceMode::None)); + checkWaitForStateChangeTimeout(); + ASSERT_TRUE(closeStream()); +} + +TEST_F(TestStreamWaitState, OutputLowWaitNonZeroSLES) { + AudioStreamBuilder builder; + builder.setPerformanceMode(PerformanceMode::LowLatency); + builder.setAudioApi(AudioApi::OpenSLES); + ASSERT_TRUE(openStream(builder)); + checkWaitForStateChangeTimeout(); + ASSERT_TRUE(closeStream()); +} + +TEST_F(TestStreamWaitState, OutputNoneWaitNonZeroSLES) { + AudioStreamBuilder builder; + builder.setPerformanceMode(PerformanceMode::None); + builder.setAudioApi(AudioApi::OpenSLES); + ASSERT_TRUE(openStream(builder)); + checkWaitForStateChangeTimeout(); + ASSERT_TRUE(closeStream()); +} + +TEST_F(TestStreamWaitState, OutputLowStopWhileWaiting) { + ASSERT_TRUE(openStream(Direction::Output, PerformanceMode::LowLatency)); + checkStopWhileWaiting(); + ASSERT_TRUE(closeStream()); +} + +TEST_F(TestStreamWaitState, OutputNoneStopWhileWaiting) { + ASSERT_TRUE(openStream(Direction::Output, PerformanceMode::LowLatency)); + checkStopWhileWaiting(); + ASSERT_TRUE(closeStream()); +} + + +TEST_F(TestStreamWaitState, OutputLowStopWhileWaitingSLES) { + AudioStreamBuilder builder; + builder.setPerformanceMode(PerformanceMode::LowLatency); + builder.setAudioApi(AudioApi::OpenSLES); + ASSERT_TRUE(openStream(builder)); + checkStopWhileWaiting(); + ASSERT_TRUE(closeStream()); +} + + +TEST_F(TestStreamWaitState, OutputLowCloseWhileWaiting) { + ASSERT_TRUE(openStream(Direction::Output, PerformanceMode::LowLatency)); + checkCloseWhileWaiting(); + ASSERT_TRUE(closeStream()); +} + +TEST_F(TestStreamWaitState, OutputNoneCloseWhileWaiting) { + ASSERT_TRUE(openStream(Direction::Output, PerformanceMode::None)); + checkCloseWhileWaiting(); + ASSERT_TRUE(closeStream()); +} + +TEST_F(TestStreamWaitState, InputLowCloseWhileWaiting) { + ASSERT_TRUE(openStream(Direction::Input, PerformanceMode::LowLatency)); + checkCloseWhileWaiting(); + ASSERT_TRUE(closeStream()); +} + +TEST_F(TestStreamWaitState, InputNoneCloseWhileWaiting) { + ASSERT_TRUE(openStream(Direction::Input, PerformanceMode::None)); + checkCloseWhileWaiting(); + ASSERT_TRUE(closeStream()); +} + +TEST_F(TestStreamWaitState, OutputNoneCloseWhileWaitingSLES) { + AudioStreamBuilder builder; + builder.setPerformanceMode(PerformanceMode::None); + builder.setAudioApi(AudioApi::OpenSLES); + ASSERT_TRUE(openStream(builder)); + checkCloseWhileWaiting(); + ASSERT_TRUE(closeStream()); +} + + +TEST_F(TestStreamWaitState, OutputLowCloseWhileWaitingSLES) { + AudioStreamBuilder builder; + builder.setPerformanceMode(PerformanceMode::LowLatency); + builder.setAudioApi(AudioApi::OpenSLES); + ASSERT_TRUE(openStream(builder)); + checkCloseWhileWaiting(); + ASSERT_TRUE(closeStream()); +} |
