diff options
author | Eric Laurent <elaurent@google.com> | 2015-05-01 11:38:42 -0700 |
---|---|---|
committer | Eric Laurent <elaurent@google.com> | 2015-05-06 10:14:42 -0700 |
commit | 296fb13dd9b5e90d6a05cce897c3b1e7914a478a (patch) | |
tree | d3ed4e6ff2902da6f556d038c71605c091b75f64 /media/libmedia/AudioTrack.cpp | |
parent | 32fa6d0e65dbf956e253a1006e9419dce2fe75c9 (diff) | |
download | frameworks_av-296fb13dd9b5e90d6a05cce897c3b1e7914a478a.zip frameworks_av-296fb13dd9b5e90d6a05cce897c3b1e7914a478a.tar.gz frameworks_av-296fb13dd9b5e90d6a05cce897c3b1e7914a478a.tar.bz2 |
Implement audio device callback
Add class AudioSystem::AudioDeviceCallback notifying
AudioSystem clients upon device selection change on a given
input or output thread.
Maintain a list of installed callback per I/O handle in AudioSystem
and call registered callbacks when an OPEN of CONFIG_CHANGED event
is received on IAudioFlingerClient::ioConfigChanged().
Add methods to AudioTrack and AudioRecord to add and remove device
change callbacks.
Add methods to AudioTrack and AudioRecord to query currently selected
device.
ioConfigChanged() events now convey the audio patch describing
the input or output thread routing.
Fix AudioRecord failure to start when invalidation is
handled by start().
Change-Id: I9e938adf025fa712337c63b1e02a8c18f2a20d39
Diffstat (limited to 'media/libmedia/AudioTrack.cpp')
-rw-r--r-- | media/libmedia/AudioTrack.cpp | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp index bb47d3e..db316b0 100644 --- a/media/libmedia/AudioTrack.cpp +++ b/media/libmedia/AudioTrack.cpp @@ -234,6 +234,10 @@ AudioTrack::~AudioTrack() mAudioTrackThread->requestExitAndWait(); mAudioTrackThread.clear(); } + // No lock here: worst case we remove a NULL callback which will be a nop + if (mDeviceCallback != 0 && mOutput != AUDIO_IO_HANDLE_NONE) { + AudioSystem::removeAudioDeviceCallback(mDeviceCallback, mOutput); + } IInterface::asBinder(mAudioTrack)->unlinkToDeath(mDeathNotifier, this); mAudioTrack.clear(); mCblkMemory.clear(); @@ -1042,6 +1046,14 @@ audio_port_handle_t AudioTrack::getOutputDevice() { return mSelectedDeviceId; } +audio_port_handle_t AudioTrack::getRoutedDeviceId() { + AutoMutex lock(mLock); + if (mOutput == AUDIO_IO_HANDLE_NONE) { + return AUDIO_PORT_HANDLE_NONE; + } + return AudioSystem::getDeviceIdForIo(mOutput); +} + status_t AudioTrack::attachAuxEffect(int effectId) { AutoMutex lock(mLock); @@ -1071,6 +1083,9 @@ status_t AudioTrack::createTrack_l() return NO_INIT; } + if (mDeviceCallback != 0 && mOutput != AUDIO_IO_HANDLE_NONE) { + AudioSystem::removeAudioDeviceCallback(mDeviceCallback, mOutput); + } audio_io_handle_t output; audio_stream_type_t streamType = mStreamType; audio_attributes_t *attr = (mStreamType == AUDIO_STREAM_DEFAULT) ? &mAttributes : NULL; @@ -1375,6 +1390,10 @@ status_t AudioTrack::createTrack_l() mDeathNotifier = new DeathNotifier(this); IInterface::asBinder(mAudioTrack)->linkToDeath(mDeathNotifier, this); + if (mDeviceCallback != 0) { + AudioSystem::addAudioDeviceCallback(mDeviceCallback, mOutput); + } + return NO_ERROR; } @@ -2308,6 +2327,48 @@ uint32_t AudioTrack::getUnderrunFrames() const return mProxy->getUnderrunFrames(); } +status_t AudioTrack::addAudioDeviceCallback(const sp<AudioSystem::AudioDeviceCallback>& callback) +{ + if (callback == 0) { + ALOGW("%s adding NULL callback!", __FUNCTION__); + return BAD_VALUE; + } + AutoMutex lock(mLock); + if (mDeviceCallback == callback) { + ALOGW("%s adding same callback!", __FUNCTION__); + return INVALID_OPERATION; + } + status_t status = NO_ERROR; + if (mOutput != AUDIO_IO_HANDLE_NONE) { + if (mDeviceCallback != 0) { + ALOGW("%s callback already present!", __FUNCTION__); + AudioSystem::removeAudioDeviceCallback(mDeviceCallback, mOutput); + } + status = AudioSystem::addAudioDeviceCallback(callback, mOutput); + } + mDeviceCallback = callback; + return status; +} + +status_t AudioTrack::removeAudioDeviceCallback( + const sp<AudioSystem::AudioDeviceCallback>& callback) +{ + if (callback == 0) { + ALOGW("%s removing NULL callback!", __FUNCTION__); + return BAD_VALUE; + } + AutoMutex lock(mLock); + if (mDeviceCallback != callback) { + ALOGW("%s removing different callback!", __FUNCTION__); + return INVALID_OPERATION; + } + if (mOutput != AUDIO_IO_HANDLE_NONE) { + AudioSystem::removeAudioDeviceCallback(mDeviceCallback, mOutput); + } + mDeviceCallback = 0; + return NO_ERROR; +} + // ========================================================================= void AudioTrack::DeathNotifier::binderDied(const wp<IBinder>& who __unused) |