Loading media/libaaudio/src/core/AudioStream.cpp +6 −6 Original line number Diff line number Diff line Loading @@ -452,8 +452,8 @@ aaudio_result_t AudioStream::createThread_l(int64_t periodNanoseconds, void* threadArg) { if (mHasThread) { ALOGE("%s() - mHasThread already true", __func__); return AAUDIO_ERROR_INVALID_STATE; ALOGD("%s() - previous thread was not joined, join now to be safe", __func__); joinThread_l(nullptr); } if (threadProc == nullptr) { return AAUDIO_ERROR_NULL; Loading @@ -462,6 +462,7 @@ aaudio_result_t AudioStream::createThread_l(int64_t periodNanoseconds, mThreadProc = threadProc; mThreadArg = threadArg; setPeriodNanoseconds(periodNanoseconds); mHasThread = true; // Prevent this object from getting deleted before the thread has a chance to create // its strong pointer. Assume the thread will call decStrong(). this->incStrong(nullptr); Loading @@ -470,6 +471,7 @@ aaudio_result_t AudioStream::createThread_l(int64_t periodNanoseconds, android::status_t status = -errno; ALOGE("%s() - pthread_create() failed, %d", __func__, status); this->decStrong(nullptr); // Because the thread won't do it. mHasThread = false; return AAudioConvert_androidToAAudioResult(status); } else { // TODO Use AAudioThread or maybe AndroidThread Loading @@ -484,7 +486,6 @@ aaudio_result_t AudioStream::createThread_l(int64_t periodNanoseconds, err = pthread_setname_np(mThread, name); ALOGW_IF((err != 0), "Could not set name of AAudio thread. err = %d", err); mHasThread = true; return AAUDIO_OK; } } Loading @@ -498,7 +499,7 @@ aaudio_result_t AudioStream::joinThread(void** returnArg) { // This must be called under mStreamLock. aaudio_result_t AudioStream::joinThread_l(void** returnArg) { if (!mHasThread) { ALOGD("joinThread() - but has no thread"); ALOGD("joinThread() - but has no thread or already join()ed"); return AAUDIO_ERROR_INVALID_STATE; } aaudio_result_t result = AAUDIO_OK; Loading @@ -515,8 +516,7 @@ aaudio_result_t AudioStream::joinThread_l(void** returnArg) { result = AAudioConvert_androidToAAudioResult(-err); } else { ALOGD("%s() pthread_join succeeded", __func__); // This must be set false so that the callback thread can be created // when the stream is restarted. // Prevent joining a second time, which has undefined behavior. mHasThread = false; } } else { Loading media/libaaudio/src/core/AudioStream.h +13 −3 Original line number Diff line number Diff line Loading @@ -157,9 +157,13 @@ public: virtual aaudio_result_t setBufferSize(int32_t requestedFrames) = 0; virtual aaudio_result_t createThread_l(int64_t periodNanoseconds, aaudio_result_t createThread(int64_t periodNanoseconds, aaudio_audio_thread_proc_t threadProc, void *threadArg); void *threadArg) EXCLUDES(mStreamLock) { std::lock_guard<std::mutex> lock(mStreamLock); return createThread_l(periodNanoseconds, threadProc, threadArg); } aaudio_result_t joinThread(void **returnArg); Loading Loading @@ -535,6 +539,11 @@ protected: mSessionId = sessionId; } aaudio_result_t createThread_l(int64_t periodNanoseconds, aaudio_audio_thread_proc_t threadProc, void *threadArg) REQUIRES(mStreamLock); aaudio_result_t joinThread_l(void **returnArg) REQUIRES(mStreamLock); std::atomic<bool> mCallbackEnabled{false}; Loading Loading @@ -658,6 +667,7 @@ private: std::atomic<pid_t> mErrorCallbackThread{CALLBACK_THREAD_NONE}; // background thread ---------------------------------- // Use mHasThread to prevent joining twice, which has undefined behavior. bool mHasThread GUARDED_BY(mStreamLock) = false; pthread_t mThread GUARDED_BY(mStreamLock) = {}; Loading services/audioflinger/Threads.cpp +22 −13 Original line number Diff line number Diff line Loading @@ -8220,6 +8220,7 @@ status_t AudioFlinger::RecordThread::shareAudioHistory( status_t AudioFlinger::RecordThread::shareAudioHistory_l( const std::string& sharedAudioPackageName, audio_session_t sharedSessionId, int64_t sharedAudioStartMs) { if ((hasAudioSession_l(sharedSessionId) & ThreadBase::TRACK_SESSION) == 0) { return BAD_VALUE; } Loading @@ -8234,18 +8235,21 @@ status_t AudioFlinger::RecordThread::shareAudioHistory_l( // after one wraparound // We assume recent wraparounds on mRsmpInRear only given it is unlikely that the requesting // app waits several hours after the start time was computed. const int64_t sharedAudioStartFrames = sharedAudioStartMs * mSampleRate / 1000; int64_t sharedAudioStartFrames = sharedAudioStartMs * mSampleRate / 1000; const int32_t sharedOffset = audio_utils::safe_sub_overflow(mRsmpInRear, (int32_t)sharedAudioStartFrames); if (sharedOffset < 0 || sharedOffset > mRsmpInFrames) { return BAD_VALUE; // Bring the start frame position within the input buffer to match the documented // "best effort" behavior of the API. if (sharedOffset < 0) { sharedAudioStartFrames = mRsmpInRear; } else if (sharedOffset > mRsmpInFrames) { sharedAudioStartFrames = audio_utils::safe_sub_overflow(mRsmpInRear, (int32_t)mRsmpInFrames); } mSharedAudioPackageName = sharedAudioPackageName; if (mSharedAudioPackageName.empty()) { mSharedAudioSessionId = AUDIO_SESSION_NONE; mSharedAudioStartFrames = -1; resetAudioHistory_l(); } else { mSharedAudioSessionId = sharedSessionId; mSharedAudioStartFrames = (int32_t)sharedAudioStartFrames; Loading @@ -8253,6 +8257,12 @@ status_t AudioFlinger::RecordThread::shareAudioHistory_l( return NO_ERROR; } void AudioFlinger::RecordThread::resetAudioHistory_l() { mSharedAudioSessionId = AUDIO_SESSION_NONE; mSharedAudioStartFrames = -1; mSharedAudioPackageName = ""; } void AudioFlinger::RecordThread::updateMetadata_l() { if (!isStreamInitialized() || !mActiveTracks.readAndClearHasChanged()) { Loading Loading @@ -8862,23 +8872,22 @@ void AudioFlinger::RecordThread::updateOutDevices(const DeviceDescriptorBaseVect int32_t AudioFlinger::RecordThread::getOldestFront_l() { if (mTracks.size() == 0) { return 0; return mRsmpInRear; } int32_t oldestFront = mRsmpInRear; int32_t maxFilled = 0; for (size_t i = 0; i < mTracks.size(); i++) { int32_t front = mTracks[i]->mResamplerBufferProvider->getFront(); int32_t filled; if (front <= mRsmpInRear) { filled = mRsmpInRear - front; } else { filled = (int32_t)((int64_t)mRsmpInRear + UINT32_MAX + 1 - front); } (void)__builtin_sub_overflow(mRsmpInRear, front, &filled); if (filled > maxFilled) { oldestFront = front; maxFilled = filled; } } if (maxFilled > mRsmpInFrames) { (void)__builtin_sub_overflow(mRsmpInRear, mRsmpInFrames, &oldestFront); } return oldestFront; } Loading Loading @@ -8928,7 +8937,7 @@ void AudioFlinger::RecordThread::resizeInputBuffer_l(int32_t maxSharedAudioHisto "resizeInputBuffer_l() called with shared history and unallocated buffer"); size_t rsmpInFrames = (size_t)maxSharedAudioHistoryMs * mSampleRate / 1000; // never reduce resampler input buffer size if (rsmpInFrames < mRsmpInFrames) { if (rsmpInFrames <= mRsmpInFrames) { return; } mRsmpInFrames = rsmpInFrames; Loading services/audioflinger/Threads.h +1 −0 Original line number Diff line number Diff line Loading @@ -1789,6 +1789,7 @@ public: status_t shareAudioHistory_l(const std::string& sharedAudioPackageName, audio_session_t sharedSessionId = AUDIO_SESSION_NONE, int64_t sharedAudioStartMs = -1); void resetAudioHistory_l(); virtual bool isStreamInitialized() { return !(mInput == nullptr || mInput->stream == nullptr); Loading services/audioflinger/Tracks.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -2458,7 +2458,7 @@ void AudioFlinger::RecordThread::RecordTrack::destroy() RecordThread *recordThread = (RecordThread *) thread.get(); priorState = mState; if (!mSharedAudioPackageName.empty()) { recordThread->shareAudioHistory_l(""); recordThread->resetAudioHistory_l(); } recordThread->destroyTrack_l(this); // move mState to STOPPED, terminate } Loading Loading
media/libaaudio/src/core/AudioStream.cpp +6 −6 Original line number Diff line number Diff line Loading @@ -452,8 +452,8 @@ aaudio_result_t AudioStream::createThread_l(int64_t periodNanoseconds, void* threadArg) { if (mHasThread) { ALOGE("%s() - mHasThread already true", __func__); return AAUDIO_ERROR_INVALID_STATE; ALOGD("%s() - previous thread was not joined, join now to be safe", __func__); joinThread_l(nullptr); } if (threadProc == nullptr) { return AAUDIO_ERROR_NULL; Loading @@ -462,6 +462,7 @@ aaudio_result_t AudioStream::createThread_l(int64_t periodNanoseconds, mThreadProc = threadProc; mThreadArg = threadArg; setPeriodNanoseconds(periodNanoseconds); mHasThread = true; // Prevent this object from getting deleted before the thread has a chance to create // its strong pointer. Assume the thread will call decStrong(). this->incStrong(nullptr); Loading @@ -470,6 +471,7 @@ aaudio_result_t AudioStream::createThread_l(int64_t periodNanoseconds, android::status_t status = -errno; ALOGE("%s() - pthread_create() failed, %d", __func__, status); this->decStrong(nullptr); // Because the thread won't do it. mHasThread = false; return AAudioConvert_androidToAAudioResult(status); } else { // TODO Use AAudioThread or maybe AndroidThread Loading @@ -484,7 +486,6 @@ aaudio_result_t AudioStream::createThread_l(int64_t periodNanoseconds, err = pthread_setname_np(mThread, name); ALOGW_IF((err != 0), "Could not set name of AAudio thread. err = %d", err); mHasThread = true; return AAUDIO_OK; } } Loading @@ -498,7 +499,7 @@ aaudio_result_t AudioStream::joinThread(void** returnArg) { // This must be called under mStreamLock. aaudio_result_t AudioStream::joinThread_l(void** returnArg) { if (!mHasThread) { ALOGD("joinThread() - but has no thread"); ALOGD("joinThread() - but has no thread or already join()ed"); return AAUDIO_ERROR_INVALID_STATE; } aaudio_result_t result = AAUDIO_OK; Loading @@ -515,8 +516,7 @@ aaudio_result_t AudioStream::joinThread_l(void** returnArg) { result = AAudioConvert_androidToAAudioResult(-err); } else { ALOGD("%s() pthread_join succeeded", __func__); // This must be set false so that the callback thread can be created // when the stream is restarted. // Prevent joining a second time, which has undefined behavior. mHasThread = false; } } else { Loading
media/libaaudio/src/core/AudioStream.h +13 −3 Original line number Diff line number Diff line Loading @@ -157,9 +157,13 @@ public: virtual aaudio_result_t setBufferSize(int32_t requestedFrames) = 0; virtual aaudio_result_t createThread_l(int64_t periodNanoseconds, aaudio_result_t createThread(int64_t periodNanoseconds, aaudio_audio_thread_proc_t threadProc, void *threadArg); void *threadArg) EXCLUDES(mStreamLock) { std::lock_guard<std::mutex> lock(mStreamLock); return createThread_l(periodNanoseconds, threadProc, threadArg); } aaudio_result_t joinThread(void **returnArg); Loading Loading @@ -535,6 +539,11 @@ protected: mSessionId = sessionId; } aaudio_result_t createThread_l(int64_t periodNanoseconds, aaudio_audio_thread_proc_t threadProc, void *threadArg) REQUIRES(mStreamLock); aaudio_result_t joinThread_l(void **returnArg) REQUIRES(mStreamLock); std::atomic<bool> mCallbackEnabled{false}; Loading Loading @@ -658,6 +667,7 @@ private: std::atomic<pid_t> mErrorCallbackThread{CALLBACK_THREAD_NONE}; // background thread ---------------------------------- // Use mHasThread to prevent joining twice, which has undefined behavior. bool mHasThread GUARDED_BY(mStreamLock) = false; pthread_t mThread GUARDED_BY(mStreamLock) = {}; Loading
services/audioflinger/Threads.cpp +22 −13 Original line number Diff line number Diff line Loading @@ -8220,6 +8220,7 @@ status_t AudioFlinger::RecordThread::shareAudioHistory( status_t AudioFlinger::RecordThread::shareAudioHistory_l( const std::string& sharedAudioPackageName, audio_session_t sharedSessionId, int64_t sharedAudioStartMs) { if ((hasAudioSession_l(sharedSessionId) & ThreadBase::TRACK_SESSION) == 0) { return BAD_VALUE; } Loading @@ -8234,18 +8235,21 @@ status_t AudioFlinger::RecordThread::shareAudioHistory_l( // after one wraparound // We assume recent wraparounds on mRsmpInRear only given it is unlikely that the requesting // app waits several hours after the start time was computed. const int64_t sharedAudioStartFrames = sharedAudioStartMs * mSampleRate / 1000; int64_t sharedAudioStartFrames = sharedAudioStartMs * mSampleRate / 1000; const int32_t sharedOffset = audio_utils::safe_sub_overflow(mRsmpInRear, (int32_t)sharedAudioStartFrames); if (sharedOffset < 0 || sharedOffset > mRsmpInFrames) { return BAD_VALUE; // Bring the start frame position within the input buffer to match the documented // "best effort" behavior of the API. if (sharedOffset < 0) { sharedAudioStartFrames = mRsmpInRear; } else if (sharedOffset > mRsmpInFrames) { sharedAudioStartFrames = audio_utils::safe_sub_overflow(mRsmpInRear, (int32_t)mRsmpInFrames); } mSharedAudioPackageName = sharedAudioPackageName; if (mSharedAudioPackageName.empty()) { mSharedAudioSessionId = AUDIO_SESSION_NONE; mSharedAudioStartFrames = -1; resetAudioHistory_l(); } else { mSharedAudioSessionId = sharedSessionId; mSharedAudioStartFrames = (int32_t)sharedAudioStartFrames; Loading @@ -8253,6 +8257,12 @@ status_t AudioFlinger::RecordThread::shareAudioHistory_l( return NO_ERROR; } void AudioFlinger::RecordThread::resetAudioHistory_l() { mSharedAudioSessionId = AUDIO_SESSION_NONE; mSharedAudioStartFrames = -1; mSharedAudioPackageName = ""; } void AudioFlinger::RecordThread::updateMetadata_l() { if (!isStreamInitialized() || !mActiveTracks.readAndClearHasChanged()) { Loading Loading @@ -8862,23 +8872,22 @@ void AudioFlinger::RecordThread::updateOutDevices(const DeviceDescriptorBaseVect int32_t AudioFlinger::RecordThread::getOldestFront_l() { if (mTracks.size() == 0) { return 0; return mRsmpInRear; } int32_t oldestFront = mRsmpInRear; int32_t maxFilled = 0; for (size_t i = 0; i < mTracks.size(); i++) { int32_t front = mTracks[i]->mResamplerBufferProvider->getFront(); int32_t filled; if (front <= mRsmpInRear) { filled = mRsmpInRear - front; } else { filled = (int32_t)((int64_t)mRsmpInRear + UINT32_MAX + 1 - front); } (void)__builtin_sub_overflow(mRsmpInRear, front, &filled); if (filled > maxFilled) { oldestFront = front; maxFilled = filled; } } if (maxFilled > mRsmpInFrames) { (void)__builtin_sub_overflow(mRsmpInRear, mRsmpInFrames, &oldestFront); } return oldestFront; } Loading Loading @@ -8928,7 +8937,7 @@ void AudioFlinger::RecordThread::resizeInputBuffer_l(int32_t maxSharedAudioHisto "resizeInputBuffer_l() called with shared history and unallocated buffer"); size_t rsmpInFrames = (size_t)maxSharedAudioHistoryMs * mSampleRate / 1000; // never reduce resampler input buffer size if (rsmpInFrames < mRsmpInFrames) { if (rsmpInFrames <= mRsmpInFrames) { return; } mRsmpInFrames = rsmpInFrames; Loading
services/audioflinger/Threads.h +1 −0 Original line number Diff line number Diff line Loading @@ -1789,6 +1789,7 @@ public: status_t shareAudioHistory_l(const std::string& sharedAudioPackageName, audio_session_t sharedSessionId = AUDIO_SESSION_NONE, int64_t sharedAudioStartMs = -1); void resetAudioHistory_l(); virtual bool isStreamInitialized() { return !(mInput == nullptr || mInput->stream == nullptr); Loading
services/audioflinger/Tracks.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -2458,7 +2458,7 @@ void AudioFlinger::RecordThread::RecordTrack::destroy() RecordThread *recordThread = (RecordThread *) thread.get(); priorState = mState; if (!mSharedAudioPackageName.empty()) { recordThread->shareAudioHistory_l(""); recordThread->resetAudioHistory_l(); } recordThread->destroyTrack_l(this); // move mState to STOPPED, terminate } Loading