aboutsummaryrefslogtreecommitdiff
path: root/externals/oboe/tests/testStreamClosedMethods.cpp
diff options
context:
space:
mode:
authorswurl <swurl@swurl.xyz>2025-05-31 02:33:02 -0400
committerswurl <swurl@swurl.xyz>2025-05-31 02:33:02 -0400
commit6c655321e6b04b8648802e296bb5ca11d290ae68 (patch)
tree5c906511e4a2910ce8b806bb9d763b524c28619e /externals/oboe/tests/testStreamClosedMethods.cpp
parentc0cceff365f754f8859f4c9a0362ebdba7ea388b (diff)
Move dead submodules in-tree
Signed-off-by: swurl <swurl@swurl.xyz>
Diffstat (limited to 'externals/oboe/tests/testStreamClosedMethods.cpp')
-rw-r--r--externals/oboe/tests/testStreamClosedMethods.cpp432
1 files changed, 432 insertions, 0 deletions
diff --git a/externals/oboe/tests/testStreamClosedMethods.cpp b/externals/oboe/tests/testStreamClosedMethods.cpp
new file mode 100644
index 0000000000..62b08596ca
--- /dev/null
+++ b/externals/oboe/tests/testStreamClosedMethods.cpp
@@ -0,0 +1,432 @@
+/*
+ * Copyright 2018 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 <gtest/gtest.h>
+#include <oboe/Oboe.h>
+
+using namespace oboe;
+
+class MyCallback : public AudioStreamDataCallback {
+public:
+ DataCallbackResult onAudioReady(AudioStream *oboeStream, void *audioData, int32_t numFrames) override {
+ return DataCallbackResult::Continue;
+ }
+};
+
+class StreamClosedReturnValues : public ::testing::Test {
+
+protected:
+
+ bool openStream() {
+ Result r = mBuilder.openStream(mStream);
+ EXPECT_EQ(r, Result::OK) << "Failed to open stream " << convertToText(r);
+ return (r == Result::OK);
+ }
+
+ bool releaseStream() {
+ Result r = mStream->release();
+ if (getSdkVersion() > __ANDROID_API_R__ && mBuilder.getAudioApi() != AudioApi::OpenSLES) {
+ EXPECT_EQ(r, Result::OK) << "Failed to release stream. " << convertToText(r);
+ return (r == Result::OK);
+ } else {
+ EXPECT_EQ(r, Result::ErrorUnimplemented) << "Did not get ErrorUnimplemented" << convertToText(r);
+ return (r == Result::ErrorUnimplemented);
+ }
+ }
+
+ bool closeStream() {
+ Result r = mStream->close();
+ EXPECT_EQ(r, Result::OK) << "Failed to close stream. " << convertToText(r);
+ return (r == Result::OK);
+ }
+
+ bool openAndCloseStream() {
+ if (!openStream() || !closeStream())
+ return false;
+ StreamState s = mStream->getState();
+ EXPECT_EQ(s, StreamState::Closed) << "Stream state " << convertToText(mStream->getState());
+ return (s == StreamState::Closed);
+ }
+
+ static int64_t getNanoseconds() {
+ struct timespec time;
+ int result = clock_gettime(CLOCK_MONOTONIC, &time);
+ if (result < 0) {
+ return result;
+ }
+ return (time.tv_sec * (int64_t)1e9) + time.tv_nsec;
+ }
+
+ // ASSERT_* requires a void return type.
+ void measureCloseTime(int32_t delayMillis) {
+ ASSERT_TRUE(openStream());
+ mStream->setDelayBeforeCloseMillis(delayMillis);
+ ASSERT_EQ(delayMillis, mStream->getDelayBeforeCloseMillis());
+ // Measure time it takes to close.
+ int64_t startTimeMillis = getNanoseconds() / 1e6;
+ ASSERT_TRUE(closeStream());
+ int64_t stopTimeMillis = getNanoseconds() / 1e6;
+ int32_t elapsedTimeMillis = (int32_t)(stopTimeMillis - startTimeMillis);
+ ASSERT_GE(elapsedTimeMillis, delayMillis);
+ }
+
+ void testDelayBeforeClose() {
+ const int32_t delayMillis = 500;
+ measureCloseTime(delayMillis);
+ }
+
+ AudioStreamBuilder mBuilder;
+ std::shared_ptr<AudioStream> mStream;
+
+};
+
+TEST_F(StreamClosedReturnValues, GetChannelCountReturnsLastKnownValue){
+
+ mBuilder.setChannelCount(2);
+ ASSERT_TRUE(openAndCloseStream());
+ ASSERT_EQ(mStream->getChannelCount(), 2);
+}
+
+TEST_F(StreamClosedReturnValues, GetDirectionReturnsLastKnownValue){
+
+ // Note that when testing on the emulator setting the direction to Input will result in ErrorInternal when
+ // opening the stream
+ mBuilder.setDirection(Direction::Input);
+ ASSERT_TRUE(openAndCloseStream());
+ ASSERT_EQ(mStream->getDirection(), Direction::Input);
+}
+
+TEST_F(StreamClosedReturnValues, GetSampleRateReturnsLastKnownValue){
+
+ mBuilder.setSampleRate(8000);
+ ASSERT_TRUE(openAndCloseStream());
+ ASSERT_EQ(mStream->getSampleRate(), 8000);
+}
+
+TEST_F(StreamClosedReturnValues, GetFramesPerCallbackReturnsLastKnownValue) {
+
+ mBuilder.setFramesPerCallback(192);
+ ASSERT_TRUE(openAndCloseStream());
+ ASSERT_EQ(mStream->getFramesPerCallback(), 192);
+}
+
+TEST_F(StreamClosedReturnValues, GetFormatReturnsLastKnownValue) {
+
+ mBuilder.setFormat(AudioFormat::I16);
+ ASSERT_TRUE(openAndCloseStream());
+ ASSERT_EQ(mStream->getFormat(), AudioFormat::I16);
+}
+
+TEST_F(StreamClosedReturnValues, GetBufferSizeInFramesReturnsLastKnownValue) {
+
+ ASSERT_TRUE(openStream());
+ int32_t bufferSize = mStream->getBufferSizeInFrames();
+ ASSERT_TRUE(closeStream());
+ ASSERT_EQ(mStream->getBufferSizeInFrames(), bufferSize);
+}
+
+TEST_F(StreamClosedReturnValues, GetBufferCapacityInFramesReturnsLastKnownValue) {
+
+ ASSERT_TRUE(openStream());
+ int32_t bufferCapacity = mStream->getBufferCapacityInFrames();
+ ASSERT_TRUE(closeStream());
+ ASSERT_EQ(mStream->getBufferCapacityInFrames(), bufferCapacity);
+}
+
+TEST_F(StreamClosedReturnValues, GetSharingModeReturnsLastKnownValue) {
+
+ ASSERT_TRUE(openStream());
+ SharingMode s = mStream->getSharingMode();
+ ASSERT_TRUE(closeStream());
+ ASSERT_EQ(mStream->getSharingMode(), s);
+}
+
+TEST_F(StreamClosedReturnValues, GetPerformanceModeReturnsLastKnownValue) {
+
+ ASSERT_TRUE(openStream());
+ PerformanceMode p = mStream->getPerformanceMode();
+ ASSERT_TRUE(closeStream());
+ ASSERT_EQ(mStream->getPerformanceMode(), p);
+}
+
+TEST_F(StreamClosedReturnValues, GetDeviceIdReturnsLastKnownValue) {
+
+ ASSERT_TRUE(openStream());
+ int32_t d = mStream->getDeviceId();
+ ASSERT_TRUE(closeStream());
+ ASSERT_EQ(mStream->getDeviceId(), d);
+}
+
+TEST_F(StreamClosedReturnValues, GetDataCallbackReturnsLastKnownValue) {
+
+ AudioStreamDataCallback *callback = new MyCallback();
+ mBuilder.setDataCallback(callback);
+ ASSERT_TRUE(openAndCloseStream());
+
+ AudioStreamDataCallback *callback2 = mStream->getDataCallback();
+ ASSERT_EQ(callback, callback2);
+}
+
+TEST_F(StreamClosedReturnValues, GetUsageReturnsLastKnownValue){
+ ASSERT_TRUE(openStream());
+ Usage u = mStream->getUsage();
+ ASSERT_TRUE(closeStream());
+ ASSERT_EQ(mStream->getUsage(), u);
+}
+
+TEST_F(StreamClosedReturnValues, GetContentTypeReturnsLastKnownValue){
+ ASSERT_TRUE(openStream());
+ ContentType c = mStream->getContentType();
+ ASSERT_TRUE(closeStream());
+ ASSERT_EQ(mStream->getContentType(), c);
+}
+
+TEST_F(StreamClosedReturnValues, GetInputPresetReturnsLastKnownValue){
+ ASSERT_TRUE(openStream());
+ auto i = mStream->getInputPreset();
+ ASSERT_TRUE(closeStream());
+ ASSERT_EQ(mStream->getInputPreset(), i);
+}
+
+TEST_F(StreamClosedReturnValues, GetSessionIdReturnsLastKnownValue){
+ ASSERT_TRUE(openStream());
+ auto s = mStream->getSessionId();
+ ASSERT_TRUE(closeStream());
+ ASSERT_EQ(mStream->getSessionId(), s);
+}
+
+TEST_F(StreamClosedReturnValues, StreamStateIsClosed){
+ ASSERT_TRUE(openAndCloseStream());
+ ASSERT_EQ(mStream->getState(), StreamState::Closed);
+}
+
+TEST_F(StreamClosedReturnValues, GetXRunCountReturnsLastKnownValue){
+
+ ASSERT_TRUE(openStream());
+ if (mStream->isXRunCountSupported()){
+ auto i = mStream->getXRunCount();
+ ASSERT_EQ(mStream->getXRunCount(), i);
+ }
+ ASSERT_TRUE(closeStream());
+}
+
+TEST_F(StreamClosedReturnValues, GetFramesPerBurstReturnsLastKnownValue){
+
+ ASSERT_TRUE(openStream());
+ auto f = mStream->getFramesPerBurst();
+ ASSERT_TRUE(closeStream());
+ ASSERT_EQ(mStream->getFramesPerBurst(), f);
+}
+
+TEST_F(StreamClosedReturnValues, GetBytesPerFrameReturnsLastKnownValue){
+ ASSERT_TRUE(openStream());
+ auto f = mStream->getBytesPerFrame();
+ ASSERT_TRUE(closeStream());
+ ASSERT_EQ(mStream->getBytesPerFrame(), f);
+}
+
+TEST_F(StreamClosedReturnValues, GetBytesPerSampleReturnsLastKnownValue){
+ ASSERT_TRUE(openStream());
+ auto f = mStream->getBytesPerSample();
+ ASSERT_TRUE(closeStream());
+ ASSERT_EQ(mStream->getBytesPerSample(), f);
+}
+
+TEST_F(StreamClosedReturnValues, GetFramesWrittenReturnsLastKnownValue){
+ mBuilder.setFormat(AudioFormat::I16);
+ mBuilder.setChannelCount(1);
+ ASSERT_TRUE(openStream());
+ ASSERT_EQ(mStream->setBufferSizeInFrames(mStream->getBufferCapacityInFrames()), Result::OK);
+ mStream->start();
+
+ int16_t buffer[4] = { 1, 2, 3, 4 };
+ Result r = mStream->write(&buffer, 4, 0);
+ if (r != Result::OK) {
+ FAIL() << "Could not write to audio stream";
+ }
+
+ auto f = mStream->getFramesWritten();
+ ASSERT_EQ(f, 4);
+
+ ASSERT_TRUE(closeStream());
+ ASSERT_EQ(mStream->getFramesWritten(), f);
+}
+
+TEST_F(StreamClosedReturnValues, GetFramesReadReturnsLastKnownValue) {
+
+ mBuilder.setDirection(Direction::Input);
+ mBuilder.setFormat(AudioFormat::I16);
+ mBuilder.setChannelCount(1);
+
+ ASSERT_TRUE(openStream());
+ mStream->start();
+
+ int16_t buffer[192];
+ auto r = mStream->read(&buffer, 192, 1000 * kNanosPerMillisecond);
+ ASSERT_EQ(r.value(), 192);
+
+ auto f = mStream->getFramesRead();
+ ASSERT_EQ(f, 192);
+
+ ASSERT_TRUE(closeStream());
+ ASSERT_EQ(mStream->getFramesRead(), f);
+}
+
+TEST_F(StreamClosedReturnValues, GetTimestampReturnsErrorClosedIfSupported){
+
+ ASSERT_TRUE(openStream());
+
+ int64_t framePosition;
+ int64_t presentationTime;
+
+ auto r = mStream->getTimestamp(CLOCK_MONOTONIC, &framePosition, &presentationTime);
+ bool isTimestampSupported = (r == Result::OK);
+
+ ASSERT_TRUE(closeStream());
+
+ if (isTimestampSupported){
+ ASSERT_EQ(mStream->getTimestamp(CLOCK_MONOTONIC, &framePosition, &presentationTime), Result::ErrorClosed);
+ }
+}
+
+TEST_F(StreamClosedReturnValues, GetAudioApiReturnsLastKnownValue){
+ ASSERT_TRUE(openStream());
+ AudioApi a = mStream->getAudioApi();
+ ASSERT_TRUE(closeStream());
+ ASSERT_EQ(mStream->getAudioApi(), a);
+}
+
+TEST_F(StreamClosedReturnValues, GetUsesAAudioReturnsLastKnownValue){
+ ASSERT_TRUE(openStream());
+ bool a = mStream->usesAAudio();
+ ASSERT_TRUE(closeStream());
+ ASSERT_EQ(mStream->usesAAudio(), a);
+}
+
+TEST_F(StreamClosedReturnValues, StreamStateControlsReturnClosed){
+
+ ASSERT_TRUE(openAndCloseStream());
+ Result r = mStream->close();
+ EXPECT_EQ(r, Result::ErrorClosed) << convertToText(r);
+ r = mStream->start();
+ EXPECT_EQ(r, Result::ErrorClosed) << convertToText(r);
+ EXPECT_EQ(mStream->pause(), Result::ErrorClosed);
+ EXPECT_EQ(mStream->flush(), Result::ErrorClosed);
+ EXPECT_EQ(mStream->stop(), Result::ErrorClosed);
+ EXPECT_EQ(mStream->requestStart(), Result::ErrorClosed);
+ EXPECT_EQ(mStream->requestPause(), Result::ErrorClosed);
+ EXPECT_EQ(mStream->requestFlush(), Result::ErrorClosed);
+ EXPECT_EQ(mStream->requestStop(), Result::ErrorClosed);
+}
+
+TEST_F(StreamClosedReturnValues, WaitForStateChangeReturnsClosed){
+
+ ASSERT_TRUE(openAndCloseStream());
+ StreamState next;
+ Result r = mStream->waitForStateChange(StreamState::Open, &next, 0);
+ EXPECT_TRUE(r == Result::OK || r == Result::ErrorClosed) << convertToText(r);
+}
+
+TEST_F(StreamClosedReturnValues, SetBufferSizeInFramesReturnsClosed){
+
+ ASSERT_TRUE(openAndCloseStream());
+ auto r = mStream->setBufferSizeInFrames(192);
+ ASSERT_EQ(r.error(), Result::ErrorClosed);
+}
+
+TEST_F(StreamClosedReturnValues, CalculateLatencyInMillisReturnsClosedIfSupported){
+
+ ASSERT_TRUE(openAndCloseStream());
+
+ if (mStream->getAudioApi() == AudioApi::AAudio){
+ auto r = mStream->calculateLatencyMillis();
+ ASSERT_EQ(r.error(), Result::ErrorInvalidState);
+ }
+}
+
+TEST_F(StreamClosedReturnValues, ReadReturnsClosed){
+
+ ASSERT_TRUE(openAndCloseStream());
+
+ int buffer[8]{0};
+ auto r = mStream->read(buffer, 1, 0);
+ ASSERT_EQ(r.error(), Result::ErrorClosed);
+}
+
+TEST_F(StreamClosedReturnValues, WriteReturnsClosed){
+
+ ASSERT_TRUE(openAndCloseStream());
+
+ int buffer[8]{0};
+ auto r = mStream->write(buffer, 1, 0);
+ ASSERT_EQ(r.error(), Result::ErrorClosed);
+}
+
+TEST_F(StreamClosedReturnValues, DelayBeforeCloseInput){
+ if (AudioStreamBuilder::isAAudioRecommended()) {
+ mBuilder.setDirection(Direction::Input);
+ testDelayBeforeClose();
+ }
+}
+
+TEST_F(StreamClosedReturnValues, DelayBeforeCloseOutput){
+ if (AudioStreamBuilder::isAAudioRecommended()) {
+ mBuilder.setDirection(Direction::Output);
+ testDelayBeforeClose();
+ }
+}
+
+TEST_F(StreamClosedReturnValues, DelayBeforeCloseInputOpenSL){
+ mBuilder.setAudioApi(AudioApi::OpenSLES);
+ mBuilder.setDirection(Direction::Input);
+ testDelayBeforeClose();
+}
+
+TEST_F(StreamClosedReturnValues, DelayBeforeCloseOutputOpenSL){
+ mBuilder.setAudioApi(AudioApi::OpenSLES);
+ mBuilder.setDirection(Direction::Output);
+ testDelayBeforeClose();
+}
+
+TEST_F(StreamClosedReturnValues, TestReleaseInput){
+ mBuilder.setDirection(Direction::Input);
+ ASSERT_TRUE(openStream());
+ ASSERT_TRUE(releaseStream());
+ ASSERT_TRUE(closeStream());
+}
+
+TEST_F(StreamClosedReturnValues, TestReleaseInputOpenSLES){
+ mBuilder.setAudioApi(AudioApi::OpenSLES);
+ mBuilder.setDirection(Direction::Input);
+ ASSERT_TRUE(openStream());
+ ASSERT_TRUE(releaseStream());
+ ASSERT_TRUE(closeStream());
+}
+
+TEST_F(StreamClosedReturnValues, TestReleaseOutput){
+ mBuilder.setDirection(Direction::Output);
+ ASSERT_TRUE(openStream());
+ ASSERT_TRUE(releaseStream());
+ ASSERT_TRUE(closeStream());
+}
+
+TEST_F(StreamClosedReturnValues, TestReleaseOutputOpenSLES){
+ mBuilder.setAudioApi(AudioApi::OpenSLES);
+ mBuilder.setDirection(Direction::Output);
+ ASSERT_TRUE(openStream());
+ ASSERT_TRUE(releaseStream());
+ ASSERT_TRUE(closeStream());
+}