Loading audio/2.0/default/StreamIn.cpp +28 −7 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <android/log.h> #include <hardware/audio.h> #include <memory> #include <utils/Trace.h> #include "StreamIn.h" Loading Loading @@ -52,7 +53,11 @@ class ReadThread : public Thread { mDataMQ(dataMQ), mStatusMQ(statusMQ), mEfGroup(efGroup), mBuffer(new uint8_t[dataMQ->getQuantumCount()]) { mBuffer(nullptr) { } bool init() { mBuffer.reset(new(std::nothrow) uint8_t[mDataMQ->getQuantumCount()]); return mBuffer != nullptr; } virtual ~ReadThread() {} Loading Loading @@ -308,8 +313,14 @@ Return<void> StreamIn::prepareForReading( return Void(); } std::unique_ptr<CommandMQ> tempCommandMQ(new CommandMQ(1)); std::unique_ptr<DataMQ> tempDataMQ( new DataMQ(frameSize * framesCount, true /* EventFlag */)); if (frameSize > std::numeric_limits<size_t>::max() / framesCount) { ALOGE("Requested buffer is too big, %d*%d can not fit in size_t", frameSize, framesCount); _hidl_cb(Result::INVALID_ARGUMENTS, CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor(), threadInfo); return Void(); } std::unique_ptr<DataMQ> tempDataMQ(new DataMQ(frameSize * framesCount, true /* EventFlag */)); std::unique_ptr<StatusMQ> tempStatusMQ(new StatusMQ(1)); if (!tempCommandMQ->isValid() || !tempDataMQ->isValid() || !tempStatusMQ->isValid()) { ALOGE_IF(!tempCommandMQ->isValid(), "command MQ is invalid"); Loading @@ -319,8 +330,11 @@ Return<void> StreamIn::prepareForReading( CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor(), threadInfo); return Void(); } status = EventFlag::createEventFlag(tempDataMQ->getEventFlagWord(), &mEfGroup); if (status != OK || !mEfGroup) { EventFlag* tempRawEfGroup{}; status = EventFlag::createEventFlag(tempDataMQ->getEventFlagWord(), &tempRawEfGroup); std::unique_ptr<EventFlag, void(*)(EventFlag*)> tempElfGroup(tempRawEfGroup, [](auto *ef) { EventFlag::deleteEventFlag(&ef); }); if (status != OK || !tempElfGroup) { ALOGE("failed creating event flag for data MQ: %s", strerror(-status)); _hidl_cb(Result::INVALID_ARGUMENTS, CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor(), threadInfo); Loading @@ -328,13 +342,18 @@ Return<void> StreamIn::prepareForReading( } // Create and launch the thread. mReadThread = new ReadThread( auto tempReadThread = std::make_unique<ReadThread>( &mStopReadThread, mStream, tempCommandMQ.get(), tempDataMQ.get(), tempStatusMQ.get(), mEfGroup); tempElfGroup.get()); if (!tempReadThread->init()) { _hidl_cb(Result::INVALID_ARGUMENTS, CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor(), threadInfo); return Void(); } status = mReadThread->run("reader", PRIORITY_URGENT_AUDIO); if (status != OK) { ALOGW("failed to start reader thread: %s", strerror(-status)); Loading @@ -346,6 +365,8 @@ Return<void> StreamIn::prepareForReading( mCommandMQ = std::move(tempCommandMQ); mDataMQ = std::move(tempDataMQ); mStatusMQ = std::move(tempStatusMQ); mReadThread = tempReadThread.release(); mEfGroup = tempElfGroup.release(); threadInfo.pid = getpid(); threadInfo.tid = mReadThread->getTid(); _hidl_cb(Result::OK, Loading audio/2.0/default/StreamOut.cpp +31 −8 Original line number Diff line number Diff line Loading @@ -18,6 +18,8 @@ //#define LOG_NDEBUG 0 #define ATRACE_TAG ATRACE_TAG_AUDIO #include <memory> #include <android/log.h> #include <hardware/audio.h> #include <utils/Trace.h> Loading Loading @@ -50,7 +52,11 @@ class WriteThread : public Thread { mDataMQ(dataMQ), mStatusMQ(statusMQ), mEfGroup(efGroup), mBuffer(new uint8_t[dataMQ->getQuantumCount()]) { mBuffer(nullptr) { } bool init() { mBuffer.reset(new(std::nothrow) uint8_t[mDataMQ->getQuantumCount()]); return mBuffer != nullptr; } virtual ~WriteThread() {} Loading Loading @@ -291,8 +297,15 @@ Return<void> StreamOut::prepareForWriting( return Void(); } std::unique_ptr<CommandMQ> tempCommandMQ(new CommandMQ(1)); std::unique_ptr<DataMQ> tempDataMQ( new DataMQ(frameSize * framesCount, true /* EventFlag */)); if (frameSize > std::numeric_limits<size_t>::max() / framesCount) { ALOGE("Requested buffer is too big, %d*%d can not fit in size_t", frameSize, framesCount); _hidl_cb(Result::INVALID_ARGUMENTS, CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor(), threadInfo); return Void(); } std::unique_ptr<DataMQ> tempDataMQ(new DataMQ(frameSize * framesCount, true /* EventFlag */)); std::unique_ptr<StatusMQ> tempStatusMQ(new StatusMQ(1)); if (!tempCommandMQ->isValid() || !tempDataMQ->isValid() || !tempStatusMQ->isValid()) { ALOGE_IF(!tempCommandMQ->isValid(), "command MQ is invalid"); Loading @@ -302,8 +315,11 @@ Return<void> StreamOut::prepareForWriting( CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor(), threadInfo); return Void(); } status = EventFlag::createEventFlag(tempDataMQ->getEventFlagWord(), &mEfGroup); if (status != OK || !mEfGroup) { EventFlag* tempRawEfGroup{}; status = EventFlag::createEventFlag(tempDataMQ->getEventFlagWord(), &tempRawEfGroup); std::unique_ptr<EventFlag, void(*)(EventFlag*)> tempElfGroup(tempRawEfGroup,[](auto *ef) { EventFlag::deleteEventFlag(&ef); }); if (status != OK || !tempElfGroup) { ALOGE("failed creating event flag for data MQ: %s", strerror(-status)); _hidl_cb(Result::INVALID_ARGUMENTS, CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor(), threadInfo); Loading @@ -311,14 +327,19 @@ Return<void> StreamOut::prepareForWriting( } // Create and launch the thread. mWriteThread = new WriteThread( auto tempWriteThread = std::make_unique<WriteThread>( &mStopWriteThread, mStream, tempCommandMQ.get(), tempDataMQ.get(), tempStatusMQ.get(), mEfGroup); status = mWriteThread->run("writer", PRIORITY_URGENT_AUDIO); tempElfGroup.get()); if (!tempWriteThread->init()) { _hidl_cb(Result::INVALID_ARGUMENTS, CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor(), threadInfo); return Void(); } status = tempWriteThread->run("writer", PRIORITY_URGENT_AUDIO); if (status != OK) { ALOGW("failed to start writer thread: %s", strerror(-status)); _hidl_cb(Result::INVALID_ARGUMENTS, Loading @@ -329,6 +350,8 @@ Return<void> StreamOut::prepareForWriting( mCommandMQ = std::move(tempCommandMQ); mDataMQ = std::move(tempDataMQ); mStatusMQ = std::move(tempStatusMQ); mWriteThread = tempWriteThread.release(); mEfGroup = tempElfGroup.release(); threadInfo.pid = getpid(); threadInfo.tid = mWriteThread->getTid(); _hidl_cb(Result::OK, Loading audio/2.0/vts/functional/AudioPrimaryHidlHalTest.cpp +13 −1 Original line number Diff line number Diff line Loading @@ -171,6 +171,7 @@ public: sp<IDevice> baseDevice; ASSERT_OK(devicesFactory->openDevice(IDevicesFactory::Device::PRIMARY, returnIn(result, baseDevice))); ASSERT_OK(result); ASSERT_TRUE(baseDevice != nullptr); environment->registerTearDown([]{ device.clear(); }); Loading Loading @@ -990,10 +991,12 @@ struct Capability { }; TEST_P(OutputStreamTest, SupportsPauseAndResumeAndDrain) { doc::test("Implementation must expose pause, resume and drain capabilities"); Capability(stream.get()); } TEST_P(OutputStreamTest, GetRenderPosition) { doc::test("The render position should be 0 on a not started"); uint32_t dspFrames; ASSERT_OK(stream->getRenderPosition(returnIn(res, dspFrames))); if (res == Result::NOT_SUPPORTED) { Loading @@ -1005,6 +1008,7 @@ TEST_P(OutputStreamTest, GetRenderPosition) { } TEST_P(OutputStreamTest, GetNextWriteTimestamp) { doc::test("The render position of a stream just created should be 0"); uint64_t timestampUs; ASSERT_OK(stream->getNextWriteTimestamp(returnIn(res, timestampUs))); if (res == Result::NOT_SUPPORTED) { Loading @@ -1030,6 +1034,7 @@ static bool isAsyncModeSupported(IStreamOut *stream) { } TEST_P(OutputStreamTest, SetCallback) { doc::test("If supported, registering callback for async operation should never fail"); if (!isAsyncModeSupported(stream.get())) { doc::partialTest("The stream does not support async operations"); return; Loading @@ -1039,6 +1044,7 @@ TEST_P(OutputStreamTest, SetCallback) { } TEST_P(OutputStreamTest, clearCallback) { doc::test("If supported, clearing a callback to go back to sync operation should not fail"); if (!isAsyncModeSupported(stream.get())) { doc::partialTest("The stream does not support async operations"); return; Loading @@ -1049,6 +1055,7 @@ TEST_P(OutputStreamTest, clearCallback) { } TEST_P(OutputStreamTest, Resume) { doc::test("If supported, a stream should fail to resume if not previously paused"); if (!Capability(stream.get()).resume) { doc::partialTest("The output stream does not support resume"); return; Loading @@ -1057,6 +1064,7 @@ TEST_P(OutputStreamTest, Resume) { } TEST_P(OutputStreamTest, Pause) { doc::test("If supported, a stream should fail to pause if not previously started"); if (!Capability(stream.get()).pause) { doc::partialTest("The output stream does not support pause"); return; Loading @@ -1066,21 +1074,24 @@ TEST_P(OutputStreamTest, Pause) { static void testDrain(IStreamOut *stream, AudioDrain type) { if (!Capability(stream).drain) { doc::partialTest("The output stream does not support pause"); doc::partialTest("The output stream does not support drain"); return; } ASSERT_RESULT(Result::OK, stream->drain(type)); } TEST_P(OutputStreamTest, DrainAll) { doc::test("If supported, a stream should always succeed to drain"); testDrain(stream.get(), AudioDrain::ALL); } TEST_P(OutputStreamTest, DrainEarlyNotify) { doc::test("If supported, a stream should always succeed to drain"); testDrain(stream.get(), AudioDrain::EARLY_NOTIFY); } TEST_P(OutputStreamTest, FlushStop) { doc::test("If supported, a stream should always succeed to flush"); auto ret = stream->flush(); ASSERT_TRUE(ret.isOk()); if (ret == Result::NOT_SUPPORTED) { Loading @@ -1091,6 +1102,7 @@ TEST_P(OutputStreamTest, FlushStop) { } TEST_P(OutputStreamTest, GetPresentationPositionStop) { doc::test("If supported, a stream should always succeed to retrieve the presentation position"); uint64_t frames; TimeSpec mesureTS; ASSERT_OK(stream->getPresentationPosition(returnIn(res, frames, mesureTS))); Loading Loading
audio/2.0/default/StreamIn.cpp +28 −7 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <android/log.h> #include <hardware/audio.h> #include <memory> #include <utils/Trace.h> #include "StreamIn.h" Loading Loading @@ -52,7 +53,11 @@ class ReadThread : public Thread { mDataMQ(dataMQ), mStatusMQ(statusMQ), mEfGroup(efGroup), mBuffer(new uint8_t[dataMQ->getQuantumCount()]) { mBuffer(nullptr) { } bool init() { mBuffer.reset(new(std::nothrow) uint8_t[mDataMQ->getQuantumCount()]); return mBuffer != nullptr; } virtual ~ReadThread() {} Loading Loading @@ -308,8 +313,14 @@ Return<void> StreamIn::prepareForReading( return Void(); } std::unique_ptr<CommandMQ> tempCommandMQ(new CommandMQ(1)); std::unique_ptr<DataMQ> tempDataMQ( new DataMQ(frameSize * framesCount, true /* EventFlag */)); if (frameSize > std::numeric_limits<size_t>::max() / framesCount) { ALOGE("Requested buffer is too big, %d*%d can not fit in size_t", frameSize, framesCount); _hidl_cb(Result::INVALID_ARGUMENTS, CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor(), threadInfo); return Void(); } std::unique_ptr<DataMQ> tempDataMQ(new DataMQ(frameSize * framesCount, true /* EventFlag */)); std::unique_ptr<StatusMQ> tempStatusMQ(new StatusMQ(1)); if (!tempCommandMQ->isValid() || !tempDataMQ->isValid() || !tempStatusMQ->isValid()) { ALOGE_IF(!tempCommandMQ->isValid(), "command MQ is invalid"); Loading @@ -319,8 +330,11 @@ Return<void> StreamIn::prepareForReading( CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor(), threadInfo); return Void(); } status = EventFlag::createEventFlag(tempDataMQ->getEventFlagWord(), &mEfGroup); if (status != OK || !mEfGroup) { EventFlag* tempRawEfGroup{}; status = EventFlag::createEventFlag(tempDataMQ->getEventFlagWord(), &tempRawEfGroup); std::unique_ptr<EventFlag, void(*)(EventFlag*)> tempElfGroup(tempRawEfGroup, [](auto *ef) { EventFlag::deleteEventFlag(&ef); }); if (status != OK || !tempElfGroup) { ALOGE("failed creating event flag for data MQ: %s", strerror(-status)); _hidl_cb(Result::INVALID_ARGUMENTS, CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor(), threadInfo); Loading @@ -328,13 +342,18 @@ Return<void> StreamIn::prepareForReading( } // Create and launch the thread. mReadThread = new ReadThread( auto tempReadThread = std::make_unique<ReadThread>( &mStopReadThread, mStream, tempCommandMQ.get(), tempDataMQ.get(), tempStatusMQ.get(), mEfGroup); tempElfGroup.get()); if (!tempReadThread->init()) { _hidl_cb(Result::INVALID_ARGUMENTS, CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor(), threadInfo); return Void(); } status = mReadThread->run("reader", PRIORITY_URGENT_AUDIO); if (status != OK) { ALOGW("failed to start reader thread: %s", strerror(-status)); Loading @@ -346,6 +365,8 @@ Return<void> StreamIn::prepareForReading( mCommandMQ = std::move(tempCommandMQ); mDataMQ = std::move(tempDataMQ); mStatusMQ = std::move(tempStatusMQ); mReadThread = tempReadThread.release(); mEfGroup = tempElfGroup.release(); threadInfo.pid = getpid(); threadInfo.tid = mReadThread->getTid(); _hidl_cb(Result::OK, Loading
audio/2.0/default/StreamOut.cpp +31 −8 Original line number Diff line number Diff line Loading @@ -18,6 +18,8 @@ //#define LOG_NDEBUG 0 #define ATRACE_TAG ATRACE_TAG_AUDIO #include <memory> #include <android/log.h> #include <hardware/audio.h> #include <utils/Trace.h> Loading Loading @@ -50,7 +52,11 @@ class WriteThread : public Thread { mDataMQ(dataMQ), mStatusMQ(statusMQ), mEfGroup(efGroup), mBuffer(new uint8_t[dataMQ->getQuantumCount()]) { mBuffer(nullptr) { } bool init() { mBuffer.reset(new(std::nothrow) uint8_t[mDataMQ->getQuantumCount()]); return mBuffer != nullptr; } virtual ~WriteThread() {} Loading Loading @@ -291,8 +297,15 @@ Return<void> StreamOut::prepareForWriting( return Void(); } std::unique_ptr<CommandMQ> tempCommandMQ(new CommandMQ(1)); std::unique_ptr<DataMQ> tempDataMQ( new DataMQ(frameSize * framesCount, true /* EventFlag */)); if (frameSize > std::numeric_limits<size_t>::max() / framesCount) { ALOGE("Requested buffer is too big, %d*%d can not fit in size_t", frameSize, framesCount); _hidl_cb(Result::INVALID_ARGUMENTS, CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor(), threadInfo); return Void(); } std::unique_ptr<DataMQ> tempDataMQ(new DataMQ(frameSize * framesCount, true /* EventFlag */)); std::unique_ptr<StatusMQ> tempStatusMQ(new StatusMQ(1)); if (!tempCommandMQ->isValid() || !tempDataMQ->isValid() || !tempStatusMQ->isValid()) { ALOGE_IF(!tempCommandMQ->isValid(), "command MQ is invalid"); Loading @@ -302,8 +315,11 @@ Return<void> StreamOut::prepareForWriting( CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor(), threadInfo); return Void(); } status = EventFlag::createEventFlag(tempDataMQ->getEventFlagWord(), &mEfGroup); if (status != OK || !mEfGroup) { EventFlag* tempRawEfGroup{}; status = EventFlag::createEventFlag(tempDataMQ->getEventFlagWord(), &tempRawEfGroup); std::unique_ptr<EventFlag, void(*)(EventFlag*)> tempElfGroup(tempRawEfGroup,[](auto *ef) { EventFlag::deleteEventFlag(&ef); }); if (status != OK || !tempElfGroup) { ALOGE("failed creating event flag for data MQ: %s", strerror(-status)); _hidl_cb(Result::INVALID_ARGUMENTS, CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor(), threadInfo); Loading @@ -311,14 +327,19 @@ Return<void> StreamOut::prepareForWriting( } // Create and launch the thread. mWriteThread = new WriteThread( auto tempWriteThread = std::make_unique<WriteThread>( &mStopWriteThread, mStream, tempCommandMQ.get(), tempDataMQ.get(), tempStatusMQ.get(), mEfGroup); status = mWriteThread->run("writer", PRIORITY_URGENT_AUDIO); tempElfGroup.get()); if (!tempWriteThread->init()) { _hidl_cb(Result::INVALID_ARGUMENTS, CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor(), threadInfo); return Void(); } status = tempWriteThread->run("writer", PRIORITY_URGENT_AUDIO); if (status != OK) { ALOGW("failed to start writer thread: %s", strerror(-status)); _hidl_cb(Result::INVALID_ARGUMENTS, Loading @@ -329,6 +350,8 @@ Return<void> StreamOut::prepareForWriting( mCommandMQ = std::move(tempCommandMQ); mDataMQ = std::move(tempDataMQ); mStatusMQ = std::move(tempStatusMQ); mWriteThread = tempWriteThread.release(); mEfGroup = tempElfGroup.release(); threadInfo.pid = getpid(); threadInfo.tid = mWriteThread->getTid(); _hidl_cb(Result::OK, Loading
audio/2.0/vts/functional/AudioPrimaryHidlHalTest.cpp +13 −1 Original line number Diff line number Diff line Loading @@ -171,6 +171,7 @@ public: sp<IDevice> baseDevice; ASSERT_OK(devicesFactory->openDevice(IDevicesFactory::Device::PRIMARY, returnIn(result, baseDevice))); ASSERT_OK(result); ASSERT_TRUE(baseDevice != nullptr); environment->registerTearDown([]{ device.clear(); }); Loading Loading @@ -990,10 +991,12 @@ struct Capability { }; TEST_P(OutputStreamTest, SupportsPauseAndResumeAndDrain) { doc::test("Implementation must expose pause, resume and drain capabilities"); Capability(stream.get()); } TEST_P(OutputStreamTest, GetRenderPosition) { doc::test("The render position should be 0 on a not started"); uint32_t dspFrames; ASSERT_OK(stream->getRenderPosition(returnIn(res, dspFrames))); if (res == Result::NOT_SUPPORTED) { Loading @@ -1005,6 +1008,7 @@ TEST_P(OutputStreamTest, GetRenderPosition) { } TEST_P(OutputStreamTest, GetNextWriteTimestamp) { doc::test("The render position of a stream just created should be 0"); uint64_t timestampUs; ASSERT_OK(stream->getNextWriteTimestamp(returnIn(res, timestampUs))); if (res == Result::NOT_SUPPORTED) { Loading @@ -1030,6 +1034,7 @@ static bool isAsyncModeSupported(IStreamOut *stream) { } TEST_P(OutputStreamTest, SetCallback) { doc::test("If supported, registering callback for async operation should never fail"); if (!isAsyncModeSupported(stream.get())) { doc::partialTest("The stream does not support async operations"); return; Loading @@ -1039,6 +1044,7 @@ TEST_P(OutputStreamTest, SetCallback) { } TEST_P(OutputStreamTest, clearCallback) { doc::test("If supported, clearing a callback to go back to sync operation should not fail"); if (!isAsyncModeSupported(stream.get())) { doc::partialTest("The stream does not support async operations"); return; Loading @@ -1049,6 +1055,7 @@ TEST_P(OutputStreamTest, clearCallback) { } TEST_P(OutputStreamTest, Resume) { doc::test("If supported, a stream should fail to resume if not previously paused"); if (!Capability(stream.get()).resume) { doc::partialTest("The output stream does not support resume"); return; Loading @@ -1057,6 +1064,7 @@ TEST_P(OutputStreamTest, Resume) { } TEST_P(OutputStreamTest, Pause) { doc::test("If supported, a stream should fail to pause if not previously started"); if (!Capability(stream.get()).pause) { doc::partialTest("The output stream does not support pause"); return; Loading @@ -1066,21 +1074,24 @@ TEST_P(OutputStreamTest, Pause) { static void testDrain(IStreamOut *stream, AudioDrain type) { if (!Capability(stream).drain) { doc::partialTest("The output stream does not support pause"); doc::partialTest("The output stream does not support drain"); return; } ASSERT_RESULT(Result::OK, stream->drain(type)); } TEST_P(OutputStreamTest, DrainAll) { doc::test("If supported, a stream should always succeed to drain"); testDrain(stream.get(), AudioDrain::ALL); } TEST_P(OutputStreamTest, DrainEarlyNotify) { doc::test("If supported, a stream should always succeed to drain"); testDrain(stream.get(), AudioDrain::EARLY_NOTIFY); } TEST_P(OutputStreamTest, FlushStop) { doc::test("If supported, a stream should always succeed to flush"); auto ret = stream->flush(); ASSERT_TRUE(ret.isOk()); if (ret == Result::NOT_SUPPORTED) { Loading @@ -1091,6 +1102,7 @@ TEST_P(OutputStreamTest, FlushStop) { } TEST_P(OutputStreamTest, GetPresentationPositionStop) { doc::test("If supported, a stream should always succeed to retrieve the presentation position"); uint64_t frames; TimeSpec mesureTS; ASSERT_OK(stream->getPresentationPosition(returnIn(res, frames, mesureTS))); Loading