/* * 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 #include 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); }