Loading services/audioflinger/Android.mk +2 −1 Original line number Diff line number Diff line Loading @@ -21,7 +21,8 @@ LOCAL_SHARED_LIBRARIES := \ libhardware \ libhardware_legacy \ libeffects \ libdl libdl \ libpowermanager LOCAL_STATIC_LIBRARIES := \ libcpustats \ Loading services/audioflinger/AudioFlinger.cpp +101 −13 Original line number Diff line number Diff line Loading @@ -53,6 +53,7 @@ #include <audio_effects/effect_visualizer.h> #include <cpustats/ThreadCpuUsage.h> #include <powermanager/PowerManager.h> // #define DEBUG_CPU_USAGE 10 // log statistics every n wall clock seconds // ---------------------------------------------------------------------------- Loading Loading @@ -887,14 +888,18 @@ void AudioFlinger::removeClient_l(pid_t pid) AudioFlinger::ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger, int id, uint32_t device) : Thread(false), mAudioFlinger(audioFlinger), mSampleRate(0), mFrameCount(0), mChannelCount(0), mFrameSize(1), mFormat(0), mStandby(false), mId(id), mExiting(false), mDevice(device) mFrameSize(1), mFormat(0), mStandby(false), mId(id), mExiting(false), mDevice(device) { mDeathRecipient = new PMDeathRecipient(this); } AudioFlinger::ThreadBase::~ThreadBase() { mParamCond.broadcast(); mNewParameters.clear(); // do not lock the mutex in destructor releaseWakeLock_l(); } void AudioFlinger::ThreadBase::exit() Loading Loading @@ -1061,6 +1066,69 @@ status_t AudioFlinger::ThreadBase::dumpEffectChains(int fd, const Vector<String1 return NO_ERROR; } void AudioFlinger::ThreadBase::acquireWakeLock() { Mutex::Autolock _l(mLock); acquireWakeLock_l(); } void AudioFlinger::ThreadBase::acquireWakeLock_l() { if (mPowerManager == 0) { // use checkService() to avoid blocking if power service is not up yet sp<IBinder> binder = defaultServiceManager()->checkService(String16("power")); if (binder == 0) { LOGW("Thread %s cannot connect to the power manager service", mName); } else { mPowerManager = interface_cast<IPowerManager>(binder); binder->linkToDeath(mDeathRecipient); } } if (mPowerManager != 0) { sp<IBinder> binder = new BBinder(); status_t status = mPowerManager->acquireWakeLock(POWERMANAGER_PARTIAL_WAKE_LOCK, binder, String16(mName)); if (status == NO_ERROR) { mWakeLockToken = binder; } LOGV("acquireWakeLock_l() %s status %d", mName, status); } } void AudioFlinger::ThreadBase::releaseWakeLock() { Mutex::Autolock _l(mLock); releaseWakeLock(); } void AudioFlinger::ThreadBase::releaseWakeLock_l() { if (mWakeLockToken != 0) { LOGV("releaseWakeLock_l() %s", mName); if (mPowerManager != 0) { mPowerManager->releaseWakeLock(mWakeLockToken, 0); } mWakeLockToken.clear(); } } void AudioFlinger::ThreadBase::clearPowerManager() { Mutex::Autolock _l(mLock); releaseWakeLock_l(); mPowerManager.clear(); } void AudioFlinger::ThreadBase::PMDeathRecipient::binderDied(const wp<IBinder>& who) { sp<ThreadBase> thread = mThread.promote(); if (thread != 0) { thread->clearPowerManager(); } LOGW("power manager service died !!!"); } // ---------------------------------------------------------------------------- Loading @@ -1072,6 +1140,8 @@ AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinge mMixBuffer(0), mSuspended(0), mBytesWritten(0), mOutput(output), mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mInWrite(false) { snprintf(mName, kNameLength, "AudioOut_%d", id); readOutputParameters(); mMasterVolume = mAudioFlinger->masterVolume(); Loading Loading @@ -1170,12 +1240,7 @@ status_t AudioFlinger::PlaybackThread::readyToRun() void AudioFlinger::PlaybackThread::onFirstRef() { const size_t SIZE = 256; char buffer[SIZE]; snprintf(buffer, SIZE, "Playback Thread %p", this); run(buffer, ANDROID_PRIORITY_URGENT_AUDIO); run(mName, ANDROID_PRIORITY_URGENT_AUDIO); } // PlaybackThread::createTrack_l() must be called with AudioFlinger::mLock held Loading Loading @@ -1522,6 +1587,8 @@ bool AudioFlinger::MixerThread::threadLoop() const CentralTendencyStatistics& stats = cpu.statistics(); #endif acquireWakeLock(); while (!exitPending()) { #ifdef DEBUG_CPU_USAGE Loading Loading @@ -1585,10 +1652,12 @@ bool AudioFlinger::MixerThread::threadLoop() if (exitPending()) break; releaseWakeLock_l(); // wait until we have something to do... LOGV("MixerThread %p TID %d going to sleep\n", this, gettid()); mWaitWorkCV.wait(mLock); LOGV("MixerThread %p TID %d waking up\n", this, gettid()); acquireWakeLock_l(); if (mMasterMute == false) { char value[PROPERTY_VALUE_MAX]; Loading Loading @@ -1689,6 +1758,8 @@ bool AudioFlinger::MixerThread::threadLoop() mOutput->stream->common.standby(&mOutput->stream->common); } releaseWakeLock(); LOGV("MixerThread %p exiting", this); return false; } Loading Loading @@ -2176,6 +2247,8 @@ bool AudioFlinger::DirectOutputThread::threadLoop() // hardware resources as soon as possible nsecs_t standbyDelay = microseconds(activeSleepTime*2); acquireWakeLock(); while (!exitPending()) { bool rampVolume; Loading Loading @@ -2215,9 +2288,11 @@ bool AudioFlinger::DirectOutputThread::threadLoop() if (exitPending()) break; releaseWakeLock_l(); LOGV("DirectOutputThread %p TID %d going to sleep\n", this, gettid()); mWaitWorkCV.wait(mLock); LOGV("DirectOutputThread %p TID %d waking up in active mode\n", this, gettid()); acquireWakeLock_l(); if (mMasterMute == false) { char value[PROPERTY_VALUE_MAX]; Loading Loading @@ -2436,6 +2511,8 @@ bool AudioFlinger::DirectOutputThread::threadLoop() mOutput->stream->common.standby(&mOutput->stream->common); } releaseWakeLock(); LOGV("DirectOutputThread %p exiting", this); return false; } Loading Loading @@ -2561,6 +2638,8 @@ bool AudioFlinger::DuplicatingThread::threadLoop() uint32_t sleepTime = idleSleepTime; Vector< sp<EffectChain> > effectChains; acquireWakeLock(); while (!exitPending()) { processConfigEvents(); Loading Loading @@ -2601,9 +2680,12 @@ bool AudioFlinger::DuplicatingThread::threadLoop() if (exitPending()) break; releaseWakeLock_l(); LOGV("DuplicatingThread %p TID %d going to sleep\n", this, gettid()); mWaitWorkCV.wait(mLock); LOGV("DuplicatingThread %p TID %d waking up\n", this, gettid()); acquireWakeLock_l(); if (mMasterMute == false) { char value[PROPERTY_VALUE_MAX]; property_get("ro.audio.silent", value, "0"); Loading Loading @@ -2690,6 +2772,8 @@ bool AudioFlinger::DuplicatingThread::threadLoop() effectChains.clear(); } releaseWakeLock(); return false; } Loading Loading @@ -3814,6 +3898,9 @@ AudioFlinger::RecordThread::RecordThread(const sp<AudioFlinger>& audioFlinger, mInput(input), mTrack(NULL), mResampler(0), mRsmpOutBuffer(0), mRsmpInBuffer(0) { mType = ThreadBase::RECORD; snprintf(mName, kNameLength, "AudioIn_%d", id); mReqChannelCount = popcount(channels); mReqSampleRate = sampleRate; readInputParameters(); Loading @@ -3831,12 +3918,7 @@ AudioFlinger::RecordThread::~RecordThread() void AudioFlinger::RecordThread::onFirstRef() { const size_t SIZE = 256; char buffer[SIZE]; snprintf(buffer, SIZE, "Record Thread %p", this); run(buffer, PRIORITY_URGENT_AUDIO); run(mName, PRIORITY_URGENT_AUDIO); } bool AudioFlinger::RecordThread::threadLoop() Loading @@ -3847,6 +3929,8 @@ bool AudioFlinger::RecordThread::threadLoop() nsecs_t lastWarning = 0; acquireWakeLock(); // start recording while (!exitPending()) { Loading @@ -3863,10 +3947,12 @@ bool AudioFlinger::RecordThread::threadLoop() if (exitPending()) break; releaseWakeLock_l(); LOGV("RecordThread: loop stopping"); // go to sleep mWaitWorkCV.wait(mLock); LOGV("RecordThread: loop starting"); acquireWakeLock_l(); continue; } if (mActiveTrack != 0) { Loading Loading @@ -4021,6 +4107,8 @@ bool AudioFlinger::RecordThread::threadLoop() mStartStopCond.broadcast(); releaseWakeLock(); LOGV("RecordThread %p exiting", this); return false; } Loading services/audioflinger/AudioFlinger.h +29 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,8 @@ #include "AudioBufferProvider.h" #include <powermanager/IPowerManager.h> namespace android { class audio_track_cblk_t; Loading Loading @@ -287,6 +289,8 @@ private: status_t dumpBase(int fd, const Vector<String16>& args); status_t dumpEffectChains(int fd, const Vector<String16>& args); void clearPowerManager(); // base for record and playback class TrackBase : public AudioBufferProvider, public RefBase { Loading Loading @@ -386,6 +390,21 @@ private: int mParam; }; class PMDeathRecipient : public IBinder::DeathRecipient { public: PMDeathRecipient(const wp<ThreadBase>& thread) : mThread(thread) {} virtual ~PMDeathRecipient() {} // IBinder::DeathRecipient virtual void binderDied(const wp<IBinder>& who); private: PMDeathRecipient(const PMDeathRecipient&); PMDeathRecipient& operator = (const PMDeathRecipient&); wp<ThreadBase> mThread; }; virtual status_t initCheck() const = 0; int type() const { return mType; } uint32_t sampleRate() const; Loading Loading @@ -462,6 +481,11 @@ private: protected: void acquireWakeLock(); void acquireWakeLock_l(); void releaseWakeLock(); void releaseWakeLock_l(); friend class Track; friend class TrackBase; friend class PlaybackThread; Loading Loading @@ -490,6 +514,11 @@ private: Vector< sp<EffectChain> > mEffectChains; uint32_t mDevice; // output device for PlaybackThread // input + output devices for RecordThread static const int kNameLength = 32; char mName[kNameLength]; sp<IPowerManager> mPowerManager; sp<IBinder> mWakeLockToken; sp<PMDeathRecipient> mDeathRecipient; }; // --- PlaybackThread --- Loading Loading
services/audioflinger/Android.mk +2 −1 Original line number Diff line number Diff line Loading @@ -21,7 +21,8 @@ LOCAL_SHARED_LIBRARIES := \ libhardware \ libhardware_legacy \ libeffects \ libdl libdl \ libpowermanager LOCAL_STATIC_LIBRARIES := \ libcpustats \ Loading
services/audioflinger/AudioFlinger.cpp +101 −13 Original line number Diff line number Diff line Loading @@ -53,6 +53,7 @@ #include <audio_effects/effect_visualizer.h> #include <cpustats/ThreadCpuUsage.h> #include <powermanager/PowerManager.h> // #define DEBUG_CPU_USAGE 10 // log statistics every n wall clock seconds // ---------------------------------------------------------------------------- Loading Loading @@ -887,14 +888,18 @@ void AudioFlinger::removeClient_l(pid_t pid) AudioFlinger::ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger, int id, uint32_t device) : Thread(false), mAudioFlinger(audioFlinger), mSampleRate(0), mFrameCount(0), mChannelCount(0), mFrameSize(1), mFormat(0), mStandby(false), mId(id), mExiting(false), mDevice(device) mFrameSize(1), mFormat(0), mStandby(false), mId(id), mExiting(false), mDevice(device) { mDeathRecipient = new PMDeathRecipient(this); } AudioFlinger::ThreadBase::~ThreadBase() { mParamCond.broadcast(); mNewParameters.clear(); // do not lock the mutex in destructor releaseWakeLock_l(); } void AudioFlinger::ThreadBase::exit() Loading Loading @@ -1061,6 +1066,69 @@ status_t AudioFlinger::ThreadBase::dumpEffectChains(int fd, const Vector<String1 return NO_ERROR; } void AudioFlinger::ThreadBase::acquireWakeLock() { Mutex::Autolock _l(mLock); acquireWakeLock_l(); } void AudioFlinger::ThreadBase::acquireWakeLock_l() { if (mPowerManager == 0) { // use checkService() to avoid blocking if power service is not up yet sp<IBinder> binder = defaultServiceManager()->checkService(String16("power")); if (binder == 0) { LOGW("Thread %s cannot connect to the power manager service", mName); } else { mPowerManager = interface_cast<IPowerManager>(binder); binder->linkToDeath(mDeathRecipient); } } if (mPowerManager != 0) { sp<IBinder> binder = new BBinder(); status_t status = mPowerManager->acquireWakeLock(POWERMANAGER_PARTIAL_WAKE_LOCK, binder, String16(mName)); if (status == NO_ERROR) { mWakeLockToken = binder; } LOGV("acquireWakeLock_l() %s status %d", mName, status); } } void AudioFlinger::ThreadBase::releaseWakeLock() { Mutex::Autolock _l(mLock); releaseWakeLock(); } void AudioFlinger::ThreadBase::releaseWakeLock_l() { if (mWakeLockToken != 0) { LOGV("releaseWakeLock_l() %s", mName); if (mPowerManager != 0) { mPowerManager->releaseWakeLock(mWakeLockToken, 0); } mWakeLockToken.clear(); } } void AudioFlinger::ThreadBase::clearPowerManager() { Mutex::Autolock _l(mLock); releaseWakeLock_l(); mPowerManager.clear(); } void AudioFlinger::ThreadBase::PMDeathRecipient::binderDied(const wp<IBinder>& who) { sp<ThreadBase> thread = mThread.promote(); if (thread != 0) { thread->clearPowerManager(); } LOGW("power manager service died !!!"); } // ---------------------------------------------------------------------------- Loading @@ -1072,6 +1140,8 @@ AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinge mMixBuffer(0), mSuspended(0), mBytesWritten(0), mOutput(output), mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mInWrite(false) { snprintf(mName, kNameLength, "AudioOut_%d", id); readOutputParameters(); mMasterVolume = mAudioFlinger->masterVolume(); Loading Loading @@ -1170,12 +1240,7 @@ status_t AudioFlinger::PlaybackThread::readyToRun() void AudioFlinger::PlaybackThread::onFirstRef() { const size_t SIZE = 256; char buffer[SIZE]; snprintf(buffer, SIZE, "Playback Thread %p", this); run(buffer, ANDROID_PRIORITY_URGENT_AUDIO); run(mName, ANDROID_PRIORITY_URGENT_AUDIO); } // PlaybackThread::createTrack_l() must be called with AudioFlinger::mLock held Loading Loading @@ -1522,6 +1587,8 @@ bool AudioFlinger::MixerThread::threadLoop() const CentralTendencyStatistics& stats = cpu.statistics(); #endif acquireWakeLock(); while (!exitPending()) { #ifdef DEBUG_CPU_USAGE Loading Loading @@ -1585,10 +1652,12 @@ bool AudioFlinger::MixerThread::threadLoop() if (exitPending()) break; releaseWakeLock_l(); // wait until we have something to do... LOGV("MixerThread %p TID %d going to sleep\n", this, gettid()); mWaitWorkCV.wait(mLock); LOGV("MixerThread %p TID %d waking up\n", this, gettid()); acquireWakeLock_l(); if (mMasterMute == false) { char value[PROPERTY_VALUE_MAX]; Loading Loading @@ -1689,6 +1758,8 @@ bool AudioFlinger::MixerThread::threadLoop() mOutput->stream->common.standby(&mOutput->stream->common); } releaseWakeLock(); LOGV("MixerThread %p exiting", this); return false; } Loading Loading @@ -2176,6 +2247,8 @@ bool AudioFlinger::DirectOutputThread::threadLoop() // hardware resources as soon as possible nsecs_t standbyDelay = microseconds(activeSleepTime*2); acquireWakeLock(); while (!exitPending()) { bool rampVolume; Loading Loading @@ -2215,9 +2288,11 @@ bool AudioFlinger::DirectOutputThread::threadLoop() if (exitPending()) break; releaseWakeLock_l(); LOGV("DirectOutputThread %p TID %d going to sleep\n", this, gettid()); mWaitWorkCV.wait(mLock); LOGV("DirectOutputThread %p TID %d waking up in active mode\n", this, gettid()); acquireWakeLock_l(); if (mMasterMute == false) { char value[PROPERTY_VALUE_MAX]; Loading Loading @@ -2436,6 +2511,8 @@ bool AudioFlinger::DirectOutputThread::threadLoop() mOutput->stream->common.standby(&mOutput->stream->common); } releaseWakeLock(); LOGV("DirectOutputThread %p exiting", this); return false; } Loading Loading @@ -2561,6 +2638,8 @@ bool AudioFlinger::DuplicatingThread::threadLoop() uint32_t sleepTime = idleSleepTime; Vector< sp<EffectChain> > effectChains; acquireWakeLock(); while (!exitPending()) { processConfigEvents(); Loading Loading @@ -2601,9 +2680,12 @@ bool AudioFlinger::DuplicatingThread::threadLoop() if (exitPending()) break; releaseWakeLock_l(); LOGV("DuplicatingThread %p TID %d going to sleep\n", this, gettid()); mWaitWorkCV.wait(mLock); LOGV("DuplicatingThread %p TID %d waking up\n", this, gettid()); acquireWakeLock_l(); if (mMasterMute == false) { char value[PROPERTY_VALUE_MAX]; property_get("ro.audio.silent", value, "0"); Loading Loading @@ -2690,6 +2772,8 @@ bool AudioFlinger::DuplicatingThread::threadLoop() effectChains.clear(); } releaseWakeLock(); return false; } Loading Loading @@ -3814,6 +3898,9 @@ AudioFlinger::RecordThread::RecordThread(const sp<AudioFlinger>& audioFlinger, mInput(input), mTrack(NULL), mResampler(0), mRsmpOutBuffer(0), mRsmpInBuffer(0) { mType = ThreadBase::RECORD; snprintf(mName, kNameLength, "AudioIn_%d", id); mReqChannelCount = popcount(channels); mReqSampleRate = sampleRate; readInputParameters(); Loading @@ -3831,12 +3918,7 @@ AudioFlinger::RecordThread::~RecordThread() void AudioFlinger::RecordThread::onFirstRef() { const size_t SIZE = 256; char buffer[SIZE]; snprintf(buffer, SIZE, "Record Thread %p", this); run(buffer, PRIORITY_URGENT_AUDIO); run(mName, PRIORITY_URGENT_AUDIO); } bool AudioFlinger::RecordThread::threadLoop() Loading @@ -3847,6 +3929,8 @@ bool AudioFlinger::RecordThread::threadLoop() nsecs_t lastWarning = 0; acquireWakeLock(); // start recording while (!exitPending()) { Loading @@ -3863,10 +3947,12 @@ bool AudioFlinger::RecordThread::threadLoop() if (exitPending()) break; releaseWakeLock_l(); LOGV("RecordThread: loop stopping"); // go to sleep mWaitWorkCV.wait(mLock); LOGV("RecordThread: loop starting"); acquireWakeLock_l(); continue; } if (mActiveTrack != 0) { Loading Loading @@ -4021,6 +4107,8 @@ bool AudioFlinger::RecordThread::threadLoop() mStartStopCond.broadcast(); releaseWakeLock(); LOGV("RecordThread %p exiting", this); return false; } Loading
services/audioflinger/AudioFlinger.h +29 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,8 @@ #include "AudioBufferProvider.h" #include <powermanager/IPowerManager.h> namespace android { class audio_track_cblk_t; Loading Loading @@ -287,6 +289,8 @@ private: status_t dumpBase(int fd, const Vector<String16>& args); status_t dumpEffectChains(int fd, const Vector<String16>& args); void clearPowerManager(); // base for record and playback class TrackBase : public AudioBufferProvider, public RefBase { Loading Loading @@ -386,6 +390,21 @@ private: int mParam; }; class PMDeathRecipient : public IBinder::DeathRecipient { public: PMDeathRecipient(const wp<ThreadBase>& thread) : mThread(thread) {} virtual ~PMDeathRecipient() {} // IBinder::DeathRecipient virtual void binderDied(const wp<IBinder>& who); private: PMDeathRecipient(const PMDeathRecipient&); PMDeathRecipient& operator = (const PMDeathRecipient&); wp<ThreadBase> mThread; }; virtual status_t initCheck() const = 0; int type() const { return mType; } uint32_t sampleRate() const; Loading Loading @@ -462,6 +481,11 @@ private: protected: void acquireWakeLock(); void acquireWakeLock_l(); void releaseWakeLock(); void releaseWakeLock_l(); friend class Track; friend class TrackBase; friend class PlaybackThread; Loading Loading @@ -490,6 +514,11 @@ private: Vector< sp<EffectChain> > mEffectChains; uint32_t mDevice; // output device for PlaybackThread // input + output devices for RecordThread static const int kNameLength = 32; char mName[kNameLength]; sp<IPowerManager> mPowerManager; sp<IBinder> mWakeLockToken; sp<PMDeathRecipient> mDeathRecipient; }; // --- PlaybackThread --- Loading