Loading media/libmedia/AudioSystem.cpp +14 −5 Original line number Diff line number Diff line Loading @@ -476,11 +476,13 @@ void AudioSystem::AudioFlingerClient::ioConfigChanged(audio_io_config_event even switch (event) { case AUDIO_OUTPUT_OPENED: case AUDIO_INPUT_OPENED: { if (getIoDescriptor(ioDesc->mIoHandle) != 0) { ALOGV("ioConfigChanged() opening already existing output! %d", ioDesc->mIoHandle); break; } sp<AudioIoDescriptor> oldDesc = getIoDescriptor(ioDesc->mIoHandle); if (oldDesc == 0) { mIoDescriptors.add(ioDesc->mIoHandle, ioDesc); } else { deviceId = oldDesc->getDeviceId(); mIoDescriptors.replaceValueFor(ioDesc->mIoHandle, ioDesc); } if (ioDesc->getDeviceId() != AUDIO_PORT_HANDLE_NONE) { deviceId = ioDesc->getDeviceId(); Loading Loading @@ -1074,7 +1076,14 @@ status_t AudioSystem::addAudioDeviceCallback( if (afc == 0) { return NO_INIT; } return afc->addAudioDeviceCallback(callback, audioIo); status_t status = afc->addAudioDeviceCallback(callback, audioIo); if (status == NO_ERROR) { const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); if (af != 0) { af->registerClient(afc); } } return status; } status_t AudioSystem::removeAudioDeviceCallback( Loading services/audioflinger/AudioFlinger.cpp +13 −15 Original line number Diff line number Diff line Loading @@ -1252,11 +1252,9 @@ void AudioFlinger::registerClient(const sp<IAudioFlingerClient>& client) if (client == 0) { return; } bool clientAdded = false; pid_t pid = IPCThreadState::self()->getCallingPid(); { Mutex::Autolock _cl(mClientLock); pid_t pid = IPCThreadState::self()->getCallingPid(); if (mNotificationClients.indexOfKey(pid) < 0) { sp<NotificationClient> notificationClient = new NotificationClient(this, client, Loading @@ -1267,22 +1265,19 @@ void AudioFlinger::registerClient(const sp<IAudioFlingerClient>& client) sp<IBinder> binder = IInterface::asBinder(client); binder->linkToDeath(notificationClient); clientAdded = true; } } // mClientLock should not be held here because ThreadBase::sendIoConfigEvent() will lock the // ThreadBase mutex and the locking order is ThreadBase::mLock then AudioFlinger::mClientLock. if (clientAdded) { // the config change is always sent from playback or record threads to avoid deadlock // with AudioSystem::gLock for (size_t i = 0; i < mPlaybackThreads.size(); i++) { mPlaybackThreads.valueAt(i)->sendIoConfigEvent(AUDIO_OUTPUT_OPENED); mPlaybackThreads.valueAt(i)->sendIoConfigEvent(AUDIO_OUTPUT_OPENED, pid); } for (size_t i = 0; i < mRecordThreads.size(); i++) { mRecordThreads.valueAt(i)->sendIoConfigEvent(AUDIO_INPUT_OPENED); } mRecordThreads.valueAt(i)->sendIoConfigEvent(AUDIO_INPUT_OPENED, pid); } } Loading Loading @@ -1316,14 +1311,17 @@ void AudioFlinger::removeNotificationClient(pid_t pid) } void AudioFlinger::ioConfigChanged(audio_io_config_event event, const sp<AudioIoDescriptor>& ioDesc) const sp<AudioIoDescriptor>& ioDesc, pid_t pid) { Mutex::Autolock _l(mClientLock); size_t size = mNotificationClients.size(); for (size_t i = 0; i < size; i++) { if ((pid == 0) || (mNotificationClients.keyAt(i) == pid)) { mNotificationClients.valueAt(i)->audioFlingerClient()->ioConfigChanged(event, ioDesc); } } } // removeClient_l() must be called with AudioFlinger::mClientLock held void AudioFlinger::removeClient_l(pid_t pid) Loading services/audioflinger/AudioFlinger.h +2 −1 Original line number Diff line number Diff line Loading @@ -559,7 +559,8 @@ private: float streamVolume_l(audio_stream_type_t stream) const { return mStreamTypes[stream].volume; } void ioConfigChanged(audio_io_config_event event, const sp<AudioIoDescriptor>& ioDesc); const sp<AudioIoDescriptor>& ioDesc, pid_t pid = 0); // Allocate an audio_io_handle_t, session ID, effect ID, or audio_module_handle_t. // They all share the same ID space, but the namespaces are actually independent Loading services/audioflinger/Threads.cpp +16 −11 Original line number Diff line number Diff line Loading @@ -532,7 +532,8 @@ AudioFlinger::ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger, audio // RecordThread::readInputParameters_l() //FIXME: mStandby should be true here. Is this some kind of hack? mStandby(false), mOutDevice(outDevice), mInDevice(inDevice), mPrevInDevice(AUDIO_DEVICE_NONE), mAudioSource(AUDIO_SOURCE_DEFAULT), mId(id), mPrevOutDevice(AUDIO_DEVICE_NONE), mPrevInDevice(AUDIO_DEVICE_NONE), mAudioSource(AUDIO_SOURCE_DEFAULT), mId(id), // mName will be set by concrete (non-virtual) subclass mDeathRecipient(new PMDeathRecipient(this)), mSystemReady(systemReady) Loading Loading @@ -627,16 +628,16 @@ status_t AudioFlinger::ThreadBase::sendConfigEvent_l(sp<ConfigEvent>& event) return status; } void AudioFlinger::ThreadBase::sendIoConfigEvent(audio_io_config_event event) void AudioFlinger::ThreadBase::sendIoConfigEvent(audio_io_config_event event, pid_t pid) { Mutex::Autolock _l(mLock); sendIoConfigEvent_l(event); sendIoConfigEvent_l(event, pid); } // sendIoConfigEvent_l() must be called with ThreadBase::mLock held void AudioFlinger::ThreadBase::sendIoConfigEvent_l(audio_io_config_event event) void AudioFlinger::ThreadBase::sendIoConfigEvent_l(audio_io_config_event event, pid_t pid) { sp<ConfigEvent> configEvent = (ConfigEvent *)new IoConfigEvent(event); sp<ConfigEvent> configEvent = (ConfigEvent *)new IoConfigEvent(event, pid); sendConfigEvent_l(configEvent); } Loading Loading @@ -706,7 +707,7 @@ void AudioFlinger::ThreadBase::processConfigEvents_l() } break; case CFG_EVENT_IO: { IoConfigEventData *data = (IoConfigEventData *)event->mData.get(); ioConfigChanged(data->mEvent); ioConfigChanged(data->mEvent, data->mPid); } break; case CFG_EVENT_SET_PARAMETER: { SetParameterConfigEventData *data = (SetParameterConfigEventData *)event->mData.get(); Loading Loading @@ -1999,7 +2000,7 @@ String8 AudioFlinger::PlaybackThread::getParameters(const String8& keys) return out_s8; } void AudioFlinger::PlaybackThread::ioConfigChanged(audio_io_config_event event) { void AudioFlinger::PlaybackThread::ioConfigChanged(audio_io_config_event event, pid_t pid) { sp<AudioIoDescriptor> desc = new AudioIoDescriptor(); ALOGV("PlaybackThread::ioConfigChanged, thread %p, event %d", this, event); Loading @@ -2021,7 +2022,7 @@ void AudioFlinger::PlaybackThread::ioConfigChanged(audio_io_config_event event) default: break; } mAudioFlinger->ioConfigChanged(event, desc); mAudioFlinger->ioConfigChanged(event, desc, pid); } void AudioFlinger::PlaybackThread::writeCallback() Loading Loading @@ -3133,7 +3134,10 @@ status_t AudioFlinger::PlaybackThread::createAudioPatch_l(const struct audio_pat for (size_t i = 0; i < mEffectChains.size(); i++) { mEffectChains[i]->setDevice_l(type); } bool configChanged = mOutDevice != type; // mPrevOutDevice is the latest device set by createAudioPatch_l(). It is not set when // the thread is created so that the first patch creation triggers an ioConfigChanged callback bool configChanged = mPrevOutDevice != type; mOutDevice = type; mPatch = *patch; Loading Loading @@ -3163,6 +3167,7 @@ status_t AudioFlinger::PlaybackThread::createAudioPatch_l(const struct audio_pat *handle = AUDIO_PATCH_HANDLE_NONE; } if (configChanged) { mPrevOutDevice = type; sendIoConfigEvent_l(AUDIO_OUTPUT_CONFIG_CHANGED); } return status; Loading Loading @@ -6868,7 +6873,7 @@ String8 AudioFlinger::RecordThread::getParameters(const String8& keys) return out_s8; } void AudioFlinger::RecordThread::ioConfigChanged(audio_io_config_event event) { void AudioFlinger::RecordThread::ioConfigChanged(audio_io_config_event event, pid_t pid) { sp<AudioIoDescriptor> desc = new AudioIoDescriptor(); desc->mIoHandle = mId; Loading @@ -6888,7 +6893,7 @@ void AudioFlinger::RecordThread::ioConfigChanged(audio_io_config_event event) { default: break; } mAudioFlinger->ioConfigChanged(event, desc); mAudioFlinger->ioConfigChanged(event, desc, pid); } void AudioFlinger::RecordThread::readInputParameters_l() Loading services/audioflinger/Threads.h +11 −9 Original line number Diff line number Diff line Loading @@ -104,21 +104,22 @@ public: class IoConfigEventData : public ConfigEventData { public: IoConfigEventData(audio_io_config_event event) : mEvent(event) {} IoConfigEventData(audio_io_config_event event, pid_t pid) : mEvent(event), mPid(pid) {} virtual void dump(char *buffer, size_t size) { snprintf(buffer, size, "IO event: event %d\n", mEvent); } const audio_io_config_event mEvent; const pid_t mPid; }; class IoConfigEvent : public ConfigEvent { public: IoConfigEvent(audio_io_config_event event) : IoConfigEvent(audio_io_config_event event, pid_t pid) : ConfigEvent(CFG_EVENT_IO) { mData = new IoConfigEventData(event); mData = new IoConfigEventData(event, pid); } virtual ~IoConfigEvent() {} }; Loading Loading @@ -255,13 +256,13 @@ public: status_t& status) = 0; virtual status_t setParameters(const String8& keyValuePairs); virtual String8 getParameters(const String8& keys) = 0; virtual void ioConfigChanged(audio_io_config_event event) = 0; virtual void ioConfigChanged(audio_io_config_event event, pid_t pid = 0) = 0; // sendConfigEvent_l() must be called with ThreadBase::mLock held // Can temporarily release the lock if waiting for a reply from // processConfigEvents_l(). status_t sendConfigEvent_l(sp<ConfigEvent>& event); void sendIoConfigEvent(audio_io_config_event event); void sendIoConfigEvent_l(audio_io_config_event event); void sendIoConfigEvent(audio_io_config_event event, pid_t pid = 0); void sendIoConfigEvent_l(audio_io_config_event event, pid_t pid = 0); void sendPrioConfigEvent(pid_t pid, pid_t tid, int32_t prio); void sendPrioConfigEvent_l(pid_t pid, pid_t tid, int32_t prio); status_t sendSetParameterConfigEvent_l(const String8& keyValuePair); Loading Loading @@ -436,6 +437,7 @@ protected: bool mStandby; // Whether thread is currently in standby. audio_devices_t mOutDevice; // output device audio_devices_t mInDevice; // input device audio_devices_t mPrevOutDevice; // previous output device audio_devices_t mPrevInDevice; // previous input device struct audio_patch mPatch; audio_source_t mAudioSource; Loading Loading @@ -572,7 +574,7 @@ public: { return android_atomic_acquire_load(&mSuspended) > 0; } virtual String8 getParameters(const String8& keys); virtual void ioConfigChanged(audio_io_config_event event); virtual void ioConfigChanged(audio_io_config_event event, pid_t pid = 0); status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames); // FIXME rename mixBuffer() to sinkBuffer() and remove int16_t* dependency. // Consider also removing and passing an explicit mMainBuffer initialization Loading Loading @@ -1254,7 +1256,7 @@ public: status_t& status); virtual void cacheParameters_l() {} virtual String8 getParameters(const String8& keys); virtual void ioConfigChanged(audio_io_config_event event); virtual void ioConfigChanged(audio_io_config_event event, pid_t pid = 0); virtual status_t createAudioPatch_l(const struct audio_patch *patch, audio_patch_handle_t *handle); virtual status_t releaseAudioPatch_l(const audio_patch_handle_t handle); Loading Loading
media/libmedia/AudioSystem.cpp +14 −5 Original line number Diff line number Diff line Loading @@ -476,11 +476,13 @@ void AudioSystem::AudioFlingerClient::ioConfigChanged(audio_io_config_event even switch (event) { case AUDIO_OUTPUT_OPENED: case AUDIO_INPUT_OPENED: { if (getIoDescriptor(ioDesc->mIoHandle) != 0) { ALOGV("ioConfigChanged() opening already existing output! %d", ioDesc->mIoHandle); break; } sp<AudioIoDescriptor> oldDesc = getIoDescriptor(ioDesc->mIoHandle); if (oldDesc == 0) { mIoDescriptors.add(ioDesc->mIoHandle, ioDesc); } else { deviceId = oldDesc->getDeviceId(); mIoDescriptors.replaceValueFor(ioDesc->mIoHandle, ioDesc); } if (ioDesc->getDeviceId() != AUDIO_PORT_HANDLE_NONE) { deviceId = ioDesc->getDeviceId(); Loading Loading @@ -1074,7 +1076,14 @@ status_t AudioSystem::addAudioDeviceCallback( if (afc == 0) { return NO_INIT; } return afc->addAudioDeviceCallback(callback, audioIo); status_t status = afc->addAudioDeviceCallback(callback, audioIo); if (status == NO_ERROR) { const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); if (af != 0) { af->registerClient(afc); } } return status; } status_t AudioSystem::removeAudioDeviceCallback( Loading
services/audioflinger/AudioFlinger.cpp +13 −15 Original line number Diff line number Diff line Loading @@ -1252,11 +1252,9 @@ void AudioFlinger::registerClient(const sp<IAudioFlingerClient>& client) if (client == 0) { return; } bool clientAdded = false; pid_t pid = IPCThreadState::self()->getCallingPid(); { Mutex::Autolock _cl(mClientLock); pid_t pid = IPCThreadState::self()->getCallingPid(); if (mNotificationClients.indexOfKey(pid) < 0) { sp<NotificationClient> notificationClient = new NotificationClient(this, client, Loading @@ -1267,22 +1265,19 @@ void AudioFlinger::registerClient(const sp<IAudioFlingerClient>& client) sp<IBinder> binder = IInterface::asBinder(client); binder->linkToDeath(notificationClient); clientAdded = true; } } // mClientLock should not be held here because ThreadBase::sendIoConfigEvent() will lock the // ThreadBase mutex and the locking order is ThreadBase::mLock then AudioFlinger::mClientLock. if (clientAdded) { // the config change is always sent from playback or record threads to avoid deadlock // with AudioSystem::gLock for (size_t i = 0; i < mPlaybackThreads.size(); i++) { mPlaybackThreads.valueAt(i)->sendIoConfigEvent(AUDIO_OUTPUT_OPENED); mPlaybackThreads.valueAt(i)->sendIoConfigEvent(AUDIO_OUTPUT_OPENED, pid); } for (size_t i = 0; i < mRecordThreads.size(); i++) { mRecordThreads.valueAt(i)->sendIoConfigEvent(AUDIO_INPUT_OPENED); } mRecordThreads.valueAt(i)->sendIoConfigEvent(AUDIO_INPUT_OPENED, pid); } } Loading Loading @@ -1316,14 +1311,17 @@ void AudioFlinger::removeNotificationClient(pid_t pid) } void AudioFlinger::ioConfigChanged(audio_io_config_event event, const sp<AudioIoDescriptor>& ioDesc) const sp<AudioIoDescriptor>& ioDesc, pid_t pid) { Mutex::Autolock _l(mClientLock); size_t size = mNotificationClients.size(); for (size_t i = 0; i < size; i++) { if ((pid == 0) || (mNotificationClients.keyAt(i) == pid)) { mNotificationClients.valueAt(i)->audioFlingerClient()->ioConfigChanged(event, ioDesc); } } } // removeClient_l() must be called with AudioFlinger::mClientLock held void AudioFlinger::removeClient_l(pid_t pid) Loading
services/audioflinger/AudioFlinger.h +2 −1 Original line number Diff line number Diff line Loading @@ -559,7 +559,8 @@ private: float streamVolume_l(audio_stream_type_t stream) const { return mStreamTypes[stream].volume; } void ioConfigChanged(audio_io_config_event event, const sp<AudioIoDescriptor>& ioDesc); const sp<AudioIoDescriptor>& ioDesc, pid_t pid = 0); // Allocate an audio_io_handle_t, session ID, effect ID, or audio_module_handle_t. // They all share the same ID space, but the namespaces are actually independent Loading
services/audioflinger/Threads.cpp +16 −11 Original line number Diff line number Diff line Loading @@ -532,7 +532,8 @@ AudioFlinger::ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger, audio // RecordThread::readInputParameters_l() //FIXME: mStandby should be true here. Is this some kind of hack? mStandby(false), mOutDevice(outDevice), mInDevice(inDevice), mPrevInDevice(AUDIO_DEVICE_NONE), mAudioSource(AUDIO_SOURCE_DEFAULT), mId(id), mPrevOutDevice(AUDIO_DEVICE_NONE), mPrevInDevice(AUDIO_DEVICE_NONE), mAudioSource(AUDIO_SOURCE_DEFAULT), mId(id), // mName will be set by concrete (non-virtual) subclass mDeathRecipient(new PMDeathRecipient(this)), mSystemReady(systemReady) Loading Loading @@ -627,16 +628,16 @@ status_t AudioFlinger::ThreadBase::sendConfigEvent_l(sp<ConfigEvent>& event) return status; } void AudioFlinger::ThreadBase::sendIoConfigEvent(audio_io_config_event event) void AudioFlinger::ThreadBase::sendIoConfigEvent(audio_io_config_event event, pid_t pid) { Mutex::Autolock _l(mLock); sendIoConfigEvent_l(event); sendIoConfigEvent_l(event, pid); } // sendIoConfigEvent_l() must be called with ThreadBase::mLock held void AudioFlinger::ThreadBase::sendIoConfigEvent_l(audio_io_config_event event) void AudioFlinger::ThreadBase::sendIoConfigEvent_l(audio_io_config_event event, pid_t pid) { sp<ConfigEvent> configEvent = (ConfigEvent *)new IoConfigEvent(event); sp<ConfigEvent> configEvent = (ConfigEvent *)new IoConfigEvent(event, pid); sendConfigEvent_l(configEvent); } Loading Loading @@ -706,7 +707,7 @@ void AudioFlinger::ThreadBase::processConfigEvents_l() } break; case CFG_EVENT_IO: { IoConfigEventData *data = (IoConfigEventData *)event->mData.get(); ioConfigChanged(data->mEvent); ioConfigChanged(data->mEvent, data->mPid); } break; case CFG_EVENT_SET_PARAMETER: { SetParameterConfigEventData *data = (SetParameterConfigEventData *)event->mData.get(); Loading Loading @@ -1999,7 +2000,7 @@ String8 AudioFlinger::PlaybackThread::getParameters(const String8& keys) return out_s8; } void AudioFlinger::PlaybackThread::ioConfigChanged(audio_io_config_event event) { void AudioFlinger::PlaybackThread::ioConfigChanged(audio_io_config_event event, pid_t pid) { sp<AudioIoDescriptor> desc = new AudioIoDescriptor(); ALOGV("PlaybackThread::ioConfigChanged, thread %p, event %d", this, event); Loading @@ -2021,7 +2022,7 @@ void AudioFlinger::PlaybackThread::ioConfigChanged(audio_io_config_event event) default: break; } mAudioFlinger->ioConfigChanged(event, desc); mAudioFlinger->ioConfigChanged(event, desc, pid); } void AudioFlinger::PlaybackThread::writeCallback() Loading Loading @@ -3133,7 +3134,10 @@ status_t AudioFlinger::PlaybackThread::createAudioPatch_l(const struct audio_pat for (size_t i = 0; i < mEffectChains.size(); i++) { mEffectChains[i]->setDevice_l(type); } bool configChanged = mOutDevice != type; // mPrevOutDevice is the latest device set by createAudioPatch_l(). It is not set when // the thread is created so that the first patch creation triggers an ioConfigChanged callback bool configChanged = mPrevOutDevice != type; mOutDevice = type; mPatch = *patch; Loading Loading @@ -3163,6 +3167,7 @@ status_t AudioFlinger::PlaybackThread::createAudioPatch_l(const struct audio_pat *handle = AUDIO_PATCH_HANDLE_NONE; } if (configChanged) { mPrevOutDevice = type; sendIoConfigEvent_l(AUDIO_OUTPUT_CONFIG_CHANGED); } return status; Loading Loading @@ -6868,7 +6873,7 @@ String8 AudioFlinger::RecordThread::getParameters(const String8& keys) return out_s8; } void AudioFlinger::RecordThread::ioConfigChanged(audio_io_config_event event) { void AudioFlinger::RecordThread::ioConfigChanged(audio_io_config_event event, pid_t pid) { sp<AudioIoDescriptor> desc = new AudioIoDescriptor(); desc->mIoHandle = mId; Loading @@ -6888,7 +6893,7 @@ void AudioFlinger::RecordThread::ioConfigChanged(audio_io_config_event event) { default: break; } mAudioFlinger->ioConfigChanged(event, desc); mAudioFlinger->ioConfigChanged(event, desc, pid); } void AudioFlinger::RecordThread::readInputParameters_l() Loading
services/audioflinger/Threads.h +11 −9 Original line number Diff line number Diff line Loading @@ -104,21 +104,22 @@ public: class IoConfigEventData : public ConfigEventData { public: IoConfigEventData(audio_io_config_event event) : mEvent(event) {} IoConfigEventData(audio_io_config_event event, pid_t pid) : mEvent(event), mPid(pid) {} virtual void dump(char *buffer, size_t size) { snprintf(buffer, size, "IO event: event %d\n", mEvent); } const audio_io_config_event mEvent; const pid_t mPid; }; class IoConfigEvent : public ConfigEvent { public: IoConfigEvent(audio_io_config_event event) : IoConfigEvent(audio_io_config_event event, pid_t pid) : ConfigEvent(CFG_EVENT_IO) { mData = new IoConfigEventData(event); mData = new IoConfigEventData(event, pid); } virtual ~IoConfigEvent() {} }; Loading Loading @@ -255,13 +256,13 @@ public: status_t& status) = 0; virtual status_t setParameters(const String8& keyValuePairs); virtual String8 getParameters(const String8& keys) = 0; virtual void ioConfigChanged(audio_io_config_event event) = 0; virtual void ioConfigChanged(audio_io_config_event event, pid_t pid = 0) = 0; // sendConfigEvent_l() must be called with ThreadBase::mLock held // Can temporarily release the lock if waiting for a reply from // processConfigEvents_l(). status_t sendConfigEvent_l(sp<ConfigEvent>& event); void sendIoConfigEvent(audio_io_config_event event); void sendIoConfigEvent_l(audio_io_config_event event); void sendIoConfigEvent(audio_io_config_event event, pid_t pid = 0); void sendIoConfigEvent_l(audio_io_config_event event, pid_t pid = 0); void sendPrioConfigEvent(pid_t pid, pid_t tid, int32_t prio); void sendPrioConfigEvent_l(pid_t pid, pid_t tid, int32_t prio); status_t sendSetParameterConfigEvent_l(const String8& keyValuePair); Loading Loading @@ -436,6 +437,7 @@ protected: bool mStandby; // Whether thread is currently in standby. audio_devices_t mOutDevice; // output device audio_devices_t mInDevice; // input device audio_devices_t mPrevOutDevice; // previous output device audio_devices_t mPrevInDevice; // previous input device struct audio_patch mPatch; audio_source_t mAudioSource; Loading Loading @@ -572,7 +574,7 @@ public: { return android_atomic_acquire_load(&mSuspended) > 0; } virtual String8 getParameters(const String8& keys); virtual void ioConfigChanged(audio_io_config_event event); virtual void ioConfigChanged(audio_io_config_event event, pid_t pid = 0); status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames); // FIXME rename mixBuffer() to sinkBuffer() and remove int16_t* dependency. // Consider also removing and passing an explicit mMainBuffer initialization Loading Loading @@ -1254,7 +1256,7 @@ public: status_t& status); virtual void cacheParameters_l() {} virtual String8 getParameters(const String8& keys); virtual void ioConfigChanged(audio_io_config_event event); virtual void ioConfigChanged(audio_io_config_event event, pid_t pid = 0); virtual status_t createAudioPatch_l(const struct audio_patch *patch, audio_patch_handle_t *handle); virtual status_t releaseAudioPatch_l(const audio_patch_handle_t handle); Loading