Loading include/media/AudioIoDescriptor.h +20 −1 Original line number Diff line number Diff line Loading @@ -33,12 +33,31 @@ enum audio_io_config_event { class AudioIoDescriptor : public RefBase { public: AudioIoDescriptor() : mIoHandle(AUDIO_IO_HANDLE_NONE), mSamplingRate(0), mFormat(AUDIO_FORMAT_DEFAULT), mChannelMask(AUDIO_CHANNEL_NONE), mFrameCount(0), mLatency(0) {} mFrameCount(0), mLatency(0) { memset(&mPatch, 0, sizeof(struct audio_patch)); } virtual ~AudioIoDescriptor() {} audio_port_handle_t getDeviceId() { if (mPatch.num_sources != 0 && mPatch.num_sinks != 0) { if (mPatch.sources[0].type == AUDIO_PORT_TYPE_MIX) { // this is an output mix // FIXME: the API only returns the first device in case of multiple device selection return mPatch.sinks[0].id; } else { // this is an input mix return mPatch.sources[0].id; } } return AUDIO_PORT_HANDLE_NONE; } audio_io_handle_t mIoHandle; struct audio_patch mPatch; uint32_t mSamplingRate; audio_format_t mFormat; audio_channel_mask_t mChannelMask; Loading include/media/AudioRecord.h +34 −0 Original line number Diff line number Diff line Loading @@ -394,6 +394,39 @@ public: * TODO Document this method. */ audio_port_handle_t getInputDevice(); /* Returns the ID of the audio device actually used by the input to which this AudioRecord * is attached. * A value of AUDIO_PORT_HANDLE_NONE indicates the AudioRecord is not attached to any input. * * Parameters: * none. */ audio_port_handle_t getRoutedDeviceId(); /* Add an AudioDeviceCallback. The caller will be notified when the audio device * to which this AudioRecord is routed is updated. * Replaces any previously installed callback. * Parameters: * callback: The callback interface * Returns NO_ERROR if successful. * INVALID_OPERATION if the same callback is already installed. * NO_INIT or PREMISSION_DENIED if AudioFlinger service is not reachable * BAD_VALUE if the callback is NULL */ status_t addAudioDeviceCallback( const sp<AudioSystem::AudioDeviceCallback>& callback); /* remove an AudioDeviceCallback. * Parameters: * callback: The callback interface * Returns NO_ERROR if successful. * INVALID_OPERATION if the callback is not installed * BAD_VALUE if the callback is NULL */ status_t removeAudioDeviceCallback( const sp<AudioSystem::AudioDeviceCallback>& callback); private: /* If nonContig is non-NULL, it is an output parameter that will be set to the number of * additional non-contiguous frames that are predicted to be available immediately, Loading Loading @@ -588,6 +621,7 @@ private: // For Device Selection API // a value of AUDIO_PORT_HANDLE_NONE indicated default (AudioPolicyManager) routing. audio_port_handle_t mSelectedDeviceId; sp<AudioSystem::AudioDeviceCallback> mDeviceCallback; }; }; // namespace android Loading include/media/AudioSystem.h +37 −6 Original line number Diff line number Diff line Loading @@ -332,8 +332,26 @@ public: }; static status_t addAudioPortCallback(const sp<AudioPortCallback>& callBack); static status_t removeAudioPortCallback(const sp<AudioPortCallback>& callBack); static status_t addAudioPortCallback(const sp<AudioPortCallback>& callback); static status_t removeAudioPortCallback(const sp<AudioPortCallback>& callback); class AudioDeviceCallback : public RefBase { public: AudioDeviceCallback() {} virtual ~AudioDeviceCallback() {} virtual void onAudioDeviceUpdate(audio_io_handle_t audioIo, audio_port_handle_t deviceId) = 0; }; static status_t addAudioDeviceCallback(const sp<AudioDeviceCallback>& callback, audio_io_handle_t audioIo); static status_t removeAudioDeviceCallback(const sp<AudioDeviceCallback>& callback, audio_io_handle_t audioIo); static audio_port_handle_t getDeviceIdForIo(audio_io_handle_t audioIo); private: Loading @@ -359,10 +377,20 @@ private: // values for output/input parameters up-to-date in client process virtual void ioConfigChanged(audio_io_config_event event, const sp<AudioIoDescriptor>& ioDesc); status_t addAudioDeviceCallback(const sp<AudioDeviceCallback>& callback, audio_io_handle_t audioIo); status_t removeAudioDeviceCallback(const sp<AudioDeviceCallback>& callback, audio_io_handle_t audioIo); audio_port_handle_t getDeviceIdForIo(audio_io_handle_t audioIo); private: Mutex mLock; DefaultKeyedVector<audio_io_handle_t, sp<AudioIoDescriptor> > mIoDescriptors; DefaultKeyedVector<audio_io_handle_t, Vector < sp<AudioDeviceCallback> > > mAudioDeviceCallbacks; // cached values for recording getInputBufferSize() queries size_t mInBuffSize; // zero indicates cache is invalid uint32_t mInSamplingRate; Loading @@ -377,8 +405,8 @@ private: AudioPolicyServiceClient() { } status_t addAudioPortCallback(const sp<AudioPortCallback>& callBack); status_t removeAudioPortCallback(const sp<AudioPortCallback>& callBack); status_t addAudioPortCallback(const sp<AudioPortCallback>& callback); status_t removeAudioPortCallback(const sp<AudioPortCallback>& callback); // DeathRecipient virtual void binderDied(const wp<IBinder>& who); Loading @@ -393,6 +421,9 @@ private: Vector <sp <AudioPortCallback> > mAudioPortCallbacks; }; static const sp<AudioFlingerClient> getAudioFlingerClient(); static sp<AudioIoDescriptor> getIoDescriptor(audio_io_handle_t ioHandle); static sp<AudioFlingerClient> gAudioFlingerClient; static sp<AudioPolicyServiceClient> gAudioPolicyServiceClient; friend class AudioFlingerClient; Loading include/media/AudioTrack.h +34 −1 Original line number Diff line number Diff line Loading @@ -510,7 +510,7 @@ public: */ status_t setOutputDevice(audio_port_handle_t deviceId); /* Returns the ID of the audio device used for output of this AudioTrack. /* Returns the ID of the audio device selected for this AudioTrack. * A value of AUDIO_PORT_HANDLE_NONE indicates default (AudioPolicyManager) routing. * * Parameters: Loading @@ -518,6 +518,15 @@ public: */ audio_port_handle_t getOutputDevice(); /* Returns the ID of the audio device actually used by the output to which this AudioTrack is * attached. * A value of AUDIO_PORT_HANDLE_NONE indicates the audio track is not attached to any output. * * Parameters: * none. */ audio_port_handle_t getRoutedDeviceId(); /* Returns the unique session ID associated with this track. * * Parameters: Loading Loading @@ -664,6 +673,28 @@ public: */ status_t getTimestamp(AudioTimestamp& timestamp); /* Add an AudioDeviceCallback. The caller will be notified when the audio device to which this * AudioTrack is routed is updated. * Replaces any previously installed callback. * Parameters: * callback: The callback interface * Returns NO_ERROR if successful. * INVALID_OPERATION if the same callback is already installed. * NO_INIT or PREMISSION_DENIED if AudioFlinger service is not reachable * BAD_VALUE if the callback is NULL */ status_t addAudioDeviceCallback(const sp<AudioSystem::AudioDeviceCallback>& callback); /* remove an AudioDeviceCallback. * Parameters: * callback: The callback interface * Returns NO_ERROR if successful. * INVALID_OPERATION if the callback is not installed * BAD_VALUE if the callback is NULL */ status_t removeAudioDeviceCallback( const sp<AudioSystem::AudioDeviceCallback>& callback); protected: /* copying audio tracks is not allowed */ AudioTrack(const AudioTrack& other); Loading Loading @@ -885,6 +916,8 @@ private: uint32_t mSequence; // incremented for each new IAudioTrack attempt int mClientUid; pid_t mClientPid; sp<AudioSystem::AudioDeviceCallback> mDeviceCallback; }; class TimedAudioTrack : public AudioTrack Loading media/libmedia/AudioRecord.cpp +70 −1 Original line number Diff line number Diff line Loading @@ -114,6 +114,10 @@ AudioRecord::~AudioRecord() mAudioRecordThread->requestExitAndWait(); mAudioRecordThread.clear(); } // No lock here: worst case we remove a NULL callback which will be a nop if (mDeviceCallback != 0 && mInput != AUDIO_IO_HANDLE_NONE) { AudioSystem::removeAudioDeviceCallback(mDeviceCallback, mInput); } IInterface::asBinder(mAudioRecord)->unlinkToDeath(mDeathNotifier, this); mAudioRecord.clear(); mCblkMemory.clear(); Loading Loading @@ -304,6 +308,8 @@ status_t AudioRecord::start(AudioSystem::sync_event_t event, int triggerSession) mNewPosition = mProxy->getPosition() + mUpdatePeriod; int32_t flags = android_atomic_acquire_load(&mCblk->mFlags); mActive = true; status_t status = NO_ERROR; if (!(flags & CBLK_INVALID)) { status = mAudioRecord->start(event, triggerSession); Loading @@ -316,9 +322,9 @@ status_t AudioRecord::start(AudioSystem::sync_event_t event, int triggerSession) } if (status != NO_ERROR) { mActive = false; ALOGE("start() status %d", status); } else { mActive = true; sp<AudioRecordThread> t = mAudioRecordThread; if (t != 0) { t->resume(); Loading Loading @@ -443,6 +449,11 @@ status_t AudioRecord::setInputDevice(audio_port_handle_t deviceId) { AutoMutex lock(mLock); if (mSelectedDeviceId != deviceId) { mSelectedDeviceId = deviceId; // stop capture so that audio policy manager does not reject the new instance start request // as only one capture can be active at a time. if (mAudioRecord != 0 && mActive) { mAudioRecord->stop(); } android_atomic_or(CBLK_INVALID, &mCblk->mFlags); } return NO_ERROR; Loading @@ -453,6 +464,14 @@ audio_port_handle_t AudioRecord::getInputDevice() { return mSelectedDeviceId; } audio_port_handle_t AudioRecord::getRoutedDeviceId() { AutoMutex lock(mLock); if (mInput == AUDIO_IO_HANDLE_NONE) { return AUDIO_PORT_HANDLE_NONE; } return AudioSystem::getDeviceIdForIo(mInput); } // ------------------------------------------------------------------------- // must be called with mLock held Loading Loading @@ -496,6 +515,10 @@ status_t AudioRecord::openRecord_l(size_t epoch, const String16& opPackageName) } } if (mDeviceCallback != 0 && mInput != AUDIO_IO_HANDLE_NONE) { AudioSystem::removeAudioDeviceCallback(mDeviceCallback, mInput); } audio_io_handle_t input; status_t status = AudioSystem::getInputForAttr(&mAttributes, &input, (audio_session_t)mSessionId, Loading Loading @@ -628,6 +651,10 @@ status_t AudioRecord::openRecord_l(size_t epoch, const String16& opPackageName) mDeathNotifier = new DeathNotifier(this); IInterface::asBinder(mAudioRecord)->linkToDeath(mDeathNotifier, this); if (mDeviceCallback != 0) { AudioSystem::addAudioDeviceCallback(mDeviceCallback, mInput); } return NO_ERROR; } Loading Loading @@ -1073,6 +1100,48 @@ status_t AudioRecord::restoreRecord_l(const char *from) return result; } status_t AudioRecord::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 (mInput != AUDIO_IO_HANDLE_NONE) { if (mDeviceCallback != 0) { ALOGW("%s callback already present!", __FUNCTION__); AudioSystem::removeAudioDeviceCallback(mDeviceCallback, mInput); } status = AudioSystem::addAudioDeviceCallback(callback, mInput); } mDeviceCallback = callback; return status; } status_t AudioRecord::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 (mInput != AUDIO_IO_HANDLE_NONE) { AudioSystem::removeAudioDeviceCallback(mDeviceCallback, mInput); } mDeviceCallback = 0; return NO_ERROR; } // ========================================================================= void AudioRecord::DeathNotifier::binderDied(const wp<IBinder>& who __unused) Loading Loading
include/media/AudioIoDescriptor.h +20 −1 Original line number Diff line number Diff line Loading @@ -33,12 +33,31 @@ enum audio_io_config_event { class AudioIoDescriptor : public RefBase { public: AudioIoDescriptor() : mIoHandle(AUDIO_IO_HANDLE_NONE), mSamplingRate(0), mFormat(AUDIO_FORMAT_DEFAULT), mChannelMask(AUDIO_CHANNEL_NONE), mFrameCount(0), mLatency(0) {} mFrameCount(0), mLatency(0) { memset(&mPatch, 0, sizeof(struct audio_patch)); } virtual ~AudioIoDescriptor() {} audio_port_handle_t getDeviceId() { if (mPatch.num_sources != 0 && mPatch.num_sinks != 0) { if (mPatch.sources[0].type == AUDIO_PORT_TYPE_MIX) { // this is an output mix // FIXME: the API only returns the first device in case of multiple device selection return mPatch.sinks[0].id; } else { // this is an input mix return mPatch.sources[0].id; } } return AUDIO_PORT_HANDLE_NONE; } audio_io_handle_t mIoHandle; struct audio_patch mPatch; uint32_t mSamplingRate; audio_format_t mFormat; audio_channel_mask_t mChannelMask; Loading
include/media/AudioRecord.h +34 −0 Original line number Diff line number Diff line Loading @@ -394,6 +394,39 @@ public: * TODO Document this method. */ audio_port_handle_t getInputDevice(); /* Returns the ID of the audio device actually used by the input to which this AudioRecord * is attached. * A value of AUDIO_PORT_HANDLE_NONE indicates the AudioRecord is not attached to any input. * * Parameters: * none. */ audio_port_handle_t getRoutedDeviceId(); /* Add an AudioDeviceCallback. The caller will be notified when the audio device * to which this AudioRecord is routed is updated. * Replaces any previously installed callback. * Parameters: * callback: The callback interface * Returns NO_ERROR if successful. * INVALID_OPERATION if the same callback is already installed. * NO_INIT or PREMISSION_DENIED if AudioFlinger service is not reachable * BAD_VALUE if the callback is NULL */ status_t addAudioDeviceCallback( const sp<AudioSystem::AudioDeviceCallback>& callback); /* remove an AudioDeviceCallback. * Parameters: * callback: The callback interface * Returns NO_ERROR if successful. * INVALID_OPERATION if the callback is not installed * BAD_VALUE if the callback is NULL */ status_t removeAudioDeviceCallback( const sp<AudioSystem::AudioDeviceCallback>& callback); private: /* If nonContig is non-NULL, it is an output parameter that will be set to the number of * additional non-contiguous frames that are predicted to be available immediately, Loading Loading @@ -588,6 +621,7 @@ private: // For Device Selection API // a value of AUDIO_PORT_HANDLE_NONE indicated default (AudioPolicyManager) routing. audio_port_handle_t mSelectedDeviceId; sp<AudioSystem::AudioDeviceCallback> mDeviceCallback; }; }; // namespace android Loading
include/media/AudioSystem.h +37 −6 Original line number Diff line number Diff line Loading @@ -332,8 +332,26 @@ public: }; static status_t addAudioPortCallback(const sp<AudioPortCallback>& callBack); static status_t removeAudioPortCallback(const sp<AudioPortCallback>& callBack); static status_t addAudioPortCallback(const sp<AudioPortCallback>& callback); static status_t removeAudioPortCallback(const sp<AudioPortCallback>& callback); class AudioDeviceCallback : public RefBase { public: AudioDeviceCallback() {} virtual ~AudioDeviceCallback() {} virtual void onAudioDeviceUpdate(audio_io_handle_t audioIo, audio_port_handle_t deviceId) = 0; }; static status_t addAudioDeviceCallback(const sp<AudioDeviceCallback>& callback, audio_io_handle_t audioIo); static status_t removeAudioDeviceCallback(const sp<AudioDeviceCallback>& callback, audio_io_handle_t audioIo); static audio_port_handle_t getDeviceIdForIo(audio_io_handle_t audioIo); private: Loading @@ -359,10 +377,20 @@ private: // values for output/input parameters up-to-date in client process virtual void ioConfigChanged(audio_io_config_event event, const sp<AudioIoDescriptor>& ioDesc); status_t addAudioDeviceCallback(const sp<AudioDeviceCallback>& callback, audio_io_handle_t audioIo); status_t removeAudioDeviceCallback(const sp<AudioDeviceCallback>& callback, audio_io_handle_t audioIo); audio_port_handle_t getDeviceIdForIo(audio_io_handle_t audioIo); private: Mutex mLock; DefaultKeyedVector<audio_io_handle_t, sp<AudioIoDescriptor> > mIoDescriptors; DefaultKeyedVector<audio_io_handle_t, Vector < sp<AudioDeviceCallback> > > mAudioDeviceCallbacks; // cached values for recording getInputBufferSize() queries size_t mInBuffSize; // zero indicates cache is invalid uint32_t mInSamplingRate; Loading @@ -377,8 +405,8 @@ private: AudioPolicyServiceClient() { } status_t addAudioPortCallback(const sp<AudioPortCallback>& callBack); status_t removeAudioPortCallback(const sp<AudioPortCallback>& callBack); status_t addAudioPortCallback(const sp<AudioPortCallback>& callback); status_t removeAudioPortCallback(const sp<AudioPortCallback>& callback); // DeathRecipient virtual void binderDied(const wp<IBinder>& who); Loading @@ -393,6 +421,9 @@ private: Vector <sp <AudioPortCallback> > mAudioPortCallbacks; }; static const sp<AudioFlingerClient> getAudioFlingerClient(); static sp<AudioIoDescriptor> getIoDescriptor(audio_io_handle_t ioHandle); static sp<AudioFlingerClient> gAudioFlingerClient; static sp<AudioPolicyServiceClient> gAudioPolicyServiceClient; friend class AudioFlingerClient; Loading
include/media/AudioTrack.h +34 −1 Original line number Diff line number Diff line Loading @@ -510,7 +510,7 @@ public: */ status_t setOutputDevice(audio_port_handle_t deviceId); /* Returns the ID of the audio device used for output of this AudioTrack. /* Returns the ID of the audio device selected for this AudioTrack. * A value of AUDIO_PORT_HANDLE_NONE indicates default (AudioPolicyManager) routing. * * Parameters: Loading @@ -518,6 +518,15 @@ public: */ audio_port_handle_t getOutputDevice(); /* Returns the ID of the audio device actually used by the output to which this AudioTrack is * attached. * A value of AUDIO_PORT_HANDLE_NONE indicates the audio track is not attached to any output. * * Parameters: * none. */ audio_port_handle_t getRoutedDeviceId(); /* Returns the unique session ID associated with this track. * * Parameters: Loading Loading @@ -664,6 +673,28 @@ public: */ status_t getTimestamp(AudioTimestamp& timestamp); /* Add an AudioDeviceCallback. The caller will be notified when the audio device to which this * AudioTrack is routed is updated. * Replaces any previously installed callback. * Parameters: * callback: The callback interface * Returns NO_ERROR if successful. * INVALID_OPERATION if the same callback is already installed. * NO_INIT or PREMISSION_DENIED if AudioFlinger service is not reachable * BAD_VALUE if the callback is NULL */ status_t addAudioDeviceCallback(const sp<AudioSystem::AudioDeviceCallback>& callback); /* remove an AudioDeviceCallback. * Parameters: * callback: The callback interface * Returns NO_ERROR if successful. * INVALID_OPERATION if the callback is not installed * BAD_VALUE if the callback is NULL */ status_t removeAudioDeviceCallback( const sp<AudioSystem::AudioDeviceCallback>& callback); protected: /* copying audio tracks is not allowed */ AudioTrack(const AudioTrack& other); Loading Loading @@ -885,6 +916,8 @@ private: uint32_t mSequence; // incremented for each new IAudioTrack attempt int mClientUid; pid_t mClientPid; sp<AudioSystem::AudioDeviceCallback> mDeviceCallback; }; class TimedAudioTrack : public AudioTrack Loading
media/libmedia/AudioRecord.cpp +70 −1 Original line number Diff line number Diff line Loading @@ -114,6 +114,10 @@ AudioRecord::~AudioRecord() mAudioRecordThread->requestExitAndWait(); mAudioRecordThread.clear(); } // No lock here: worst case we remove a NULL callback which will be a nop if (mDeviceCallback != 0 && mInput != AUDIO_IO_HANDLE_NONE) { AudioSystem::removeAudioDeviceCallback(mDeviceCallback, mInput); } IInterface::asBinder(mAudioRecord)->unlinkToDeath(mDeathNotifier, this); mAudioRecord.clear(); mCblkMemory.clear(); Loading Loading @@ -304,6 +308,8 @@ status_t AudioRecord::start(AudioSystem::sync_event_t event, int triggerSession) mNewPosition = mProxy->getPosition() + mUpdatePeriod; int32_t flags = android_atomic_acquire_load(&mCblk->mFlags); mActive = true; status_t status = NO_ERROR; if (!(flags & CBLK_INVALID)) { status = mAudioRecord->start(event, triggerSession); Loading @@ -316,9 +322,9 @@ status_t AudioRecord::start(AudioSystem::sync_event_t event, int triggerSession) } if (status != NO_ERROR) { mActive = false; ALOGE("start() status %d", status); } else { mActive = true; sp<AudioRecordThread> t = mAudioRecordThread; if (t != 0) { t->resume(); Loading Loading @@ -443,6 +449,11 @@ status_t AudioRecord::setInputDevice(audio_port_handle_t deviceId) { AutoMutex lock(mLock); if (mSelectedDeviceId != deviceId) { mSelectedDeviceId = deviceId; // stop capture so that audio policy manager does not reject the new instance start request // as only one capture can be active at a time. if (mAudioRecord != 0 && mActive) { mAudioRecord->stop(); } android_atomic_or(CBLK_INVALID, &mCblk->mFlags); } return NO_ERROR; Loading @@ -453,6 +464,14 @@ audio_port_handle_t AudioRecord::getInputDevice() { return mSelectedDeviceId; } audio_port_handle_t AudioRecord::getRoutedDeviceId() { AutoMutex lock(mLock); if (mInput == AUDIO_IO_HANDLE_NONE) { return AUDIO_PORT_HANDLE_NONE; } return AudioSystem::getDeviceIdForIo(mInput); } // ------------------------------------------------------------------------- // must be called with mLock held Loading Loading @@ -496,6 +515,10 @@ status_t AudioRecord::openRecord_l(size_t epoch, const String16& opPackageName) } } if (mDeviceCallback != 0 && mInput != AUDIO_IO_HANDLE_NONE) { AudioSystem::removeAudioDeviceCallback(mDeviceCallback, mInput); } audio_io_handle_t input; status_t status = AudioSystem::getInputForAttr(&mAttributes, &input, (audio_session_t)mSessionId, Loading Loading @@ -628,6 +651,10 @@ status_t AudioRecord::openRecord_l(size_t epoch, const String16& opPackageName) mDeathNotifier = new DeathNotifier(this); IInterface::asBinder(mAudioRecord)->linkToDeath(mDeathNotifier, this); if (mDeviceCallback != 0) { AudioSystem::addAudioDeviceCallback(mDeviceCallback, mInput); } return NO_ERROR; } Loading Loading @@ -1073,6 +1100,48 @@ status_t AudioRecord::restoreRecord_l(const char *from) return result; } status_t AudioRecord::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 (mInput != AUDIO_IO_HANDLE_NONE) { if (mDeviceCallback != 0) { ALOGW("%s callback already present!", __FUNCTION__); AudioSystem::removeAudioDeviceCallback(mDeviceCallback, mInput); } status = AudioSystem::addAudioDeviceCallback(callback, mInput); } mDeviceCallback = callback; return status; } status_t AudioRecord::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 (mInput != AUDIO_IO_HANDLE_NONE) { AudioSystem::removeAudioDeviceCallback(mDeviceCallback, mInput); } mDeviceCallback = 0; return NO_ERROR; } // ========================================================================= void AudioRecord::DeathNotifier::binderDied(const wp<IBinder>& who __unused) Loading