| /* |
| * 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 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); |
| } |
| |
| AudioStreamBuilder mBuilder; |
| AudioStream *mStream = nullptr; |
| |
| }; |
| |
| 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()); |
| 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); |
| } |
| |
| // TODO: Reading a positive value doesn't work on OpenSL ES in this test - why? |
| 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, 0); |
| 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); |
| ASSERT_EQ(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::ErrorClosed); |
| } |
| } |
| |
| 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); |
| } |