Loading services/audioflinger/AudioFlinger.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -412,6 +412,7 @@ void AudioFlinger::onFirstRef() mAAudioHwBurstMinMicros = getAAudioHardwareBurstMinUsecFromSystemProperty(); } mPatchPanel = IAfPatchPanel::create(sp<IAfPatchPanelCallback>::fromExisting(this)); mMelReporter = sp<MelReporter>::make(sp<IAfMelReporterCallback>::fromExisting(this)); } Loading services/audioflinger/AudioFlinger.h +40 −34 Original line number Diff line number Diff line Loading @@ -167,10 +167,10 @@ class AudioFlinger , public IAfClientCallback , public IAfDeviceEffectManagerCallback , public IAfMelReporterCallback , public IAfPatchPanelCallback { friend class sp<AudioFlinger>; // TODO(b/291319167) Create interface and remove friends. friend class PatchPanel; // TODO(b/291012167) replace the Thread friends with an interface. friend class DirectOutputThread; friend class MixerThread; Loading Loading @@ -375,7 +375,7 @@ public: // ---- begin IAfDeviceEffectManagerCallback interface bool isAudioPolicyReady() const final { return mAudioPolicyReady.load(); } // below also used by IAfMelReporterCallback // below also used by IAfMelReporterCallback, IAfPatchPanelCallback const sp<PatchCommandThread>& getPatchCommandThread() final { return mPatchCommandThread; } status_t addEffectToHal( const struct audio_port_config* device, const sp<EffectHalInterface>& effect) final; Loading @@ -391,6 +391,41 @@ public: // ---- end of IAfMelReporterCallback interface // ---- begin IAfPatchPanelCallback interface void closeThreadInternal_l(const sp<IAfPlaybackThread>& thread) final; void closeThreadInternal_l(const sp<IAfRecordThread>& thread) final; // return thread associated with primary hardware device, or NULL IAfPlaybackThread* primaryPlaybackThread_l() const final; IAfPlaybackThread* checkPlaybackThread_l(audio_io_handle_t output) const final; IAfRecordThread* checkRecordThread_l(audio_io_handle_t input) const final; IAfMmapThread* checkMmapThread_l(audio_io_handle_t io) const final; void lock() const final ACQUIRE(mLock) { mLock.lock(); } void unlock() const final RELEASE(mLock) { mLock.unlock(); } sp<IAfThreadBase> openInput_l(audio_module_handle_t module, audio_io_handle_t* input, audio_config_t* config, audio_devices_t device, const char* address, audio_source_t source, audio_input_flags_t flags, audio_devices_t outputDevice, const String8& outputDeviceAddress) final; sp<IAfThreadBase> openOutput_l(audio_module_handle_t module, audio_io_handle_t* output, audio_config_t* halConfig, audio_config_base_t* mixerConfig, audio_devices_t deviceType, const String8& address, audio_output_flags_t flags) final; const DefaultKeyedVector<audio_module_handle_t, AudioHwDevice*>& getAudioHwDevs_l() const final { return mAudioHwDevs; } void updateDownStreamPatches_l(const struct audio_patch* patch, const std::set<audio_io_handle_t>& streams) final; void updateOutDevicesForRecordThreads_l(const DeviceDescriptorBaseVector& devices) final; // ---- end of IAfPatchPanelCallback interface /* List available audio ports and their attributes */ status_t listAudioPorts(unsigned int* num_ports, struct audio_port* ports) const; Loading @@ -412,9 +447,6 @@ public: const sp<os::ExternalVibration>& externalVibration); static void onExternalVibrationStop(const sp<os::ExternalVibration>& externalVibration); void updateDownStreamPatches_l(const struct audio_patch *patch, const std::set<audio_io_handle_t>& streams); std::optional<media::AudioVibratorInfo> getDefaultVibratorInfo_l(); private: Loading Loading @@ -454,9 +486,6 @@ public: bool btNrecIsOff() const { return mBtNrecIsOff.load(); } void lock() ACQUIRE(mLock) { mLock.lock(); } void unlock() RELEASE(mLock) { mLock.unlock(); } private: audio_mode_t getMode() const { return mMode; } Loading Loading @@ -628,29 +657,11 @@ private: } IAfThreadBase* checkThread_l(audio_io_handle_t ioHandle) const; IAfPlaybackThread* checkPlaybackThread_l(audio_io_handle_t output) const; IAfPlaybackThread* checkMixerThread_l(audio_io_handle_t output) const; IAfRecordThread* checkRecordThread_l(audio_io_handle_t input) const; IAfMmapThread* checkMmapThread_l(audio_io_handle_t io) const; sp<VolumeInterface> getVolumeInterface_l(audio_io_handle_t output) const; std::vector<sp<VolumeInterface>> getAllVolumeInterfaces_l() const; sp<IAfThreadBase> openInput_l(audio_module_handle_t module, audio_io_handle_t *input, audio_config_t *config, audio_devices_t device, const char* address, audio_source_t source, audio_input_flags_t flags, audio_devices_t outputDevice, const String8& outputDeviceAddress); sp<IAfThreadBase> openOutput_l(audio_module_handle_t module, audio_io_handle_t *output, audio_config_t *halConfig, audio_config_base_t *mixerConfig, audio_devices_t deviceType, const String8& address, audio_output_flags_t flags); void closeOutputFinish(const sp<IAfPlaybackThread>& thread); void closeInputFinish(const sp<IAfRecordThread>& thread); Loading @@ -675,14 +686,13 @@ private: // Thus it may fail by returning an ID of the wrong sign, // or by returning a non-unique ID. // This is the internal API. For the binder API see newAudioUniqueId(). // used by IAfDeviceEffectManagerCallback // used by IAfDeviceEffectManagerCallback, IAfPatchPanelCallback audio_unique_id_t nextUniqueId(audio_unique_id_use_t use) final; status_t moveEffectChain_l(audio_session_t sessionId, IAfPlaybackThread* srcThread, IAfPlaybackThread* dstThread); // return thread associated with primary hardware device, or NULL IAfPlaybackThread* primaryPlaybackThread_l() const; DeviceTypeSet primaryOutputDevice_l() const; // return the playback thread with smallest HAL buffer size, and prefer fast Loading Loading @@ -726,7 +736,6 @@ private: std::vector< sp<IAfEffectModule> > purgeStaleEffects_l(); void broadcastParametersToRecordThreads_l(const String8& keyValuePairs); void updateOutDevicesForRecordThreads_l(const DeviceDescriptorBaseVector& devices); void forwardParametersToDownstreamPatches_l( audio_io_handle_t upStream, const String8& keyValuePairs, const std::function<bool(const sp<IAfPlaybackThread>&)>& useThread = nullptr); Loading Loading @@ -844,9 +853,7 @@ private: // for use from destructor status_t closeOutput_nonvirtual(audio_io_handle_t output); void closeThreadInternal_l(const sp<IAfPlaybackThread>& thread); status_t closeInput_nonvirtual(audio_io_handle_t input); void closeThreadInternal_l(const sp<IAfRecordThread>& thread); void setAudioHwSyncForSession_l(IAfPlaybackThread* thread, audio_session_t sessionId); status_t checkStreamType(audio_stream_type_t stream) const; Loading @@ -873,8 +880,7 @@ private: nsecs_t mGlobalEffectEnableTime; // when a global effect was last enabled // protected by mLock const sp<IAfPatchPanel> mPatchPanel = IAfPatchPanel::create(this); /* const */ sp<IAfPatchPanel> mPatchPanel; public: // TODO(b/291319167) access by getter. Loading services/audioflinger/IAfPatchPanel.h +38 −1 Original line number Diff line number Diff line Loading @@ -18,12 +18,14 @@ namespace android { class IAfMmapThread; class IAfPatchPanel; class IAfPatchRecord; class IAfPatchTrack; class IAfPlaybackThread; class IAfRecordThread; class IAfThreadBase; class PatchCommandThread; class SoftwarePatch { public: Loading Loading @@ -51,9 +53,44 @@ private: const audio_io_handle_t mRecordThreadHandle; }; class IAfPatchPanelCallback : public virtual RefBase { public: virtual void closeThreadInternal_l(const sp<IAfPlaybackThread>& thread) = 0; virtual void closeThreadInternal_l(const sp<IAfRecordThread>& thread) = 0; virtual IAfPlaybackThread* primaryPlaybackThread_l() const = 0; virtual IAfPlaybackThread* checkPlaybackThread_l(audio_io_handle_t output) const = 0; virtual IAfRecordThread* checkRecordThread_l(audio_io_handle_t input) const = 0; virtual IAfMmapThread* checkMmapThread_l(audio_io_handle_t io) const = 0; virtual sp<IAfThreadBase> openInput_l(audio_module_handle_t module, audio_io_handle_t* input, audio_config_t* config, audio_devices_t device, const char* address, audio_source_t source, audio_input_flags_t flags, audio_devices_t outputDevice, const String8& outputDeviceAddress) = 0; virtual sp<IAfThreadBase> openOutput_l(audio_module_handle_t module, audio_io_handle_t* output, audio_config_t* halConfig, audio_config_base_t* mixerConfig, audio_devices_t deviceType, const String8& address, audio_output_flags_t flags) = 0; virtual void lock() const = 0; virtual void unlock() const = 0; virtual const DefaultKeyedVector<audio_module_handle_t, AudioHwDevice*>& getAudioHwDevs_l() const = 0; virtual audio_unique_id_t nextUniqueId(audio_unique_id_use_t use) = 0; virtual const sp<PatchCommandThread>& getPatchCommandThread() = 0; virtual void updateDownStreamPatches_l( const struct audio_patch* patch, const std::set<audio_io_handle_t>& streams) = 0; virtual void updateOutDevicesForRecordThreads_l(const DeviceDescriptorBaseVector& devices) = 0; }; class IAfPatchPanel : public virtual RefBase { public: static sp<IAfPatchPanel> create(AudioFlinger* audioFlinger); static sp<IAfPatchPanel> create(const sp<IAfPatchPanelCallback>& afPatchPanelCallback); // Extraction of inner Endpoint and Patch classes would require interfaces // (in the Endpoint case a templated interface) but that seems Loading services/audioflinger/PatchPanel.cpp +39 −36 Original line number Diff line number Diff line Loading @@ -96,8 +96,8 @@ status_t AudioFlinger::listAudioPatches( } /* static */ sp<IAfPatchPanel> IAfPatchPanel::create(AudioFlinger* audioFlinger) { return sp<PatchPanel>::make(audioFlinger); sp<IAfPatchPanel> IAfPatchPanel::create(const sp<IAfPatchPanelCallback>& afPatchPanelCallback) { return sp<PatchPanel>::make(afPatchPanelCallback); } status_t SoftwarePatch::getLatencyMs_l(double* latencyMs) const { Loading @@ -119,10 +119,10 @@ void PatchPanel::closeThreadInternal_l(const sp<IAfThreadBase>& thread) const { if (const auto recordThread = thread->asIAfRecordThread(); recordThread) { mAudioFlinger.closeThreadInternal_l(recordThread); mAfPatchPanelCallback->closeThreadInternal_l(recordThread); } else if (const auto playbackThread = thread->asIAfPlaybackThread(); playbackThread) { mAudioFlinger.closeThreadInternal_l(playbackThread); mAfPatchPanelCallback->closeThreadInternal_l(playbackThread); } else { LOG_ALWAYS_FATAL("%s: Endpoints only accept IAfPlayback and IAfRecord threads, " "invalid thread, id: %d type: %d", Loading Loading @@ -275,8 +275,8 @@ status_t PatchPanel::createAudioPatch(const struct audio_patch* patch, status = INVALID_OPERATION; goto exit; } const sp<IAfThreadBase> thread = mAudioFlinger.checkPlaybackThread_l(patch->sources[1].ext.mix.handle); const sp<IAfThreadBase> thread = mAfPatchPanelCallback->checkPlaybackThread_l( patch->sources[1].ext.mix.handle); if (thread == 0) { ALOGW("%s() cannot get playback thread", __func__); status = INVALID_OPERATION; Loading @@ -302,7 +302,7 @@ status_t PatchPanel::createAudioPatch(const struct audio_patch* patch, if (patch->sinks[0].config_mask & AUDIO_PORT_CONFIG_FLAGS) { flags = patch->sinks[0].flags.output; } const sp<IAfThreadBase> thread = mAudioFlinger.openOutput_l( const sp<IAfThreadBase> thread = mAfPatchPanelCallback->openOutput_l( patch->sinks[0].ext.device.hw_module, &output, &config, Loading @@ -310,7 +310,7 @@ status_t PatchPanel::createAudioPatch(const struct audio_patch* patch, outputDevice, outputDeviceAddress, flags); ALOGV("mAudioFlinger.openOutput_l() returned %p", thread.get()); ALOGV("mAfPatchPanelCallback->openOutput_l() returned %p", thread.get()); if (thread == 0) { status = NO_MEMORY; goto exit; Loading Loading @@ -349,7 +349,7 @@ status_t PatchPanel::createAudioPatch(const struct audio_patch* patch, == AUDIO_STREAM_VOICE_CALL) { source = AUDIO_SOURCE_VOICE_COMMUNICATION; } const sp<IAfThreadBase> thread = mAudioFlinger.openInput_l(srcModule, const sp<IAfThreadBase> thread = mAfPatchPanelCallback->openInput_l(srcModule, &input, &config, device, Loading @@ -358,7 +358,7 @@ status_t PatchPanel::createAudioPatch(const struct audio_patch* patch, flags, outputDevice, outputDeviceAddress); ALOGV("mAudioFlinger.openInput_l() returned %p inChannelMask %08x", ALOGV("mAfPatchPanelCallback->openInput_l() returned %p inChannelMask %08x", thread.get(), config.channel_mask); if (thread == 0) { status = NO_MEMORY; Loading @@ -374,10 +374,11 @@ status_t PatchPanel::createAudioPatch(const struct audio_patch* patch, } } else { if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) { sp<IAfThreadBase> thread = mAudioFlinger.checkRecordThread_l( sp<IAfThreadBase> thread = mAfPatchPanelCallback->checkRecordThread_l( patch->sinks[0].ext.mix.handle); if (thread == 0) { thread = mAudioFlinger.checkMmapThread_l(patch->sinks[0].ext.mix.handle); thread = mAfPatchPanelCallback->checkMmapThread_l( patch->sinks[0].ext.mix.handle); if (thread == 0) { ALOGW("%s() bad capture I/O handle %d", __func__, patch->sinks[0].ext.mix.handle); Loading @@ -385,9 +386,9 @@ status_t PatchPanel::createAudioPatch(const struct audio_patch* patch, goto exit; } } mAudioFlinger.unlock(); mAfPatchPanelCallback->unlock(); status = thread->sendCreateAudioPatchConfigEvent(patch, &halHandle); mAudioFlinger.lock(); mAfPatchPanelCallback->lock(); if (status == NO_ERROR) { newPatch.setThread(thread); } Loading @@ -411,7 +412,7 @@ status_t PatchPanel::createAudioPatch(const struct audio_patch* patch, } break; case AUDIO_PORT_TYPE_MIX: { audio_module_handle_t srcModule = patch->sources[0].ext.mix.hw_module; ssize_t index = mAudioFlinger.mAudioHwDevs.indexOfKey(srcModule); ssize_t index = mAfPatchPanelCallback->getAudioHwDevs_l().indexOfKey(srcModule); if (index < 0) { ALOGW("%s() bad src hw module %d", __func__, srcModule); status = BAD_VALUE; Loading @@ -437,10 +438,11 @@ status_t PatchPanel::createAudioPatch(const struct audio_patch* patch, device->applyAudioPortConfig(&patch->sinks[i]); devices.push_back(device); } sp<IAfThreadBase> thread = mAudioFlinger.checkPlaybackThread_l(patch->sources[0].ext.mix.handle); sp<IAfThreadBase> thread = mAfPatchPanelCallback->checkPlaybackThread_l( patch->sources[0].ext.mix.handle); if (thread == 0) { thread = mAudioFlinger.checkMmapThread_l(patch->sources[0].ext.mix.handle); thread = mAfPatchPanelCallback->checkMmapThread_l( patch->sources[0].ext.mix.handle); if (thread == 0) { ALOGW("%s() bad playback I/O handle %d", __func__, patch->sources[0].ext.mix.handle); Loading @@ -448,13 +450,13 @@ status_t PatchPanel::createAudioPatch(const struct audio_patch* patch, goto exit; } } if (thread == mAudioFlinger.primaryPlaybackThread_l()) { mAudioFlinger.updateOutDevicesForRecordThreads_l(devices); if (thread == mAfPatchPanelCallback->primaryPlaybackThread_l()) { mAfPatchPanelCallback->updateOutDevicesForRecordThreads_l(devices); } mAudioFlinger.unlock(); mAfPatchPanelCallback->unlock(); status = thread->sendCreateAudioPatchConfigEvent(patch, &halHandle); mAudioFlinger.lock(); mAfPatchPanelCallback->lock(); if (status == NO_ERROR) { newPatch.setThread(thread); } Loading @@ -479,9 +481,10 @@ status_t PatchPanel::createAudioPatch(const struct audio_patch* patch, exit: ALOGV("%s() status %d", __func__, status); if (status == NO_ERROR) { *handle = (audio_patch_handle_t) mAudioFlinger.nextUniqueId(AUDIO_UNIQUE_ID_USE_PATCH); *handle = static_cast<audio_patch_handle_t>( mAfPatchPanelCallback->nextUniqueId(AUDIO_UNIQUE_ID_USE_PATCH)); newPatch.mHalHandle = halHandle; mAudioFlinger.mPatchCommandThread->createAudioPatch(*handle, newPatch); mAfPatchPanelCallback->getPatchCommandThread()->createAudioPatch(*handle, newPatch); if (insertedModule != AUDIO_MODULE_HANDLE_NONE) { addSoftwarePatchToInsertedModules(insertedModule, *handle, &newPatch.mAudioPatch); } Loading Loading @@ -793,18 +796,18 @@ status_t PatchPanel::releaseAudioPatch(audio_patch_handle_t handle) if (patch.sinks[0].type == AUDIO_PORT_TYPE_MIX) { audio_io_handle_t ioHandle = patch.sinks[0].ext.mix.handle; sp<IAfThreadBase> thread = mAudioFlinger.checkRecordThread_l(ioHandle); sp<IAfThreadBase> thread = mAfPatchPanelCallback->checkRecordThread_l(ioHandle); if (thread == 0) { thread = mAudioFlinger.checkMmapThread_l(ioHandle); thread = mAfPatchPanelCallback->checkMmapThread_l(ioHandle); if (thread == 0) { ALOGW("%s() bad capture I/O handle %d", __func__, ioHandle); status = BAD_VALUE; break; } } mAudioFlinger.unlock(); mAfPatchPanelCallback->unlock(); status = thread->sendReleaseAudioPatchConfigEvent(removedPatch.mHalHandle); mAudioFlinger.lock(); mAfPatchPanelCallback->lock(); } else { status = hwDevice->releaseAudioPatch(removedPatch.mHalHandle); } Loading @@ -816,18 +819,18 @@ status_t PatchPanel::releaseAudioPatch(audio_patch_handle_t handle) break; } audio_io_handle_t ioHandle = src.ext.mix.handle; sp<IAfThreadBase> thread = mAudioFlinger.checkPlaybackThread_l(ioHandle); sp<IAfThreadBase> thread = mAfPatchPanelCallback->checkPlaybackThread_l(ioHandle); if (thread == 0) { thread = mAudioFlinger.checkMmapThread_l(ioHandle); thread = mAfPatchPanelCallback->checkMmapThread_l(ioHandle); if (thread == 0) { ALOGW("%s() bad playback I/O handle %d", __func__, ioHandle); status = BAD_VALUE; break; } } mAudioFlinger.unlock(); mAfPatchPanelCallback->unlock(); status = thread->sendReleaseAudioPatchConfigEvent(removedPatch.mHalHandle); mAudioFlinger.lock(); mAfPatchPanelCallback->lock(); } break; default: status = BAD_VALUE; Loading @@ -840,7 +843,7 @@ status_t PatchPanel::releaseAudioPatch(audio_patch_handle_t handle) void PatchPanel::erasePatch(audio_patch_handle_t handle) { mPatches.erase(handle); removeSoftwarePatchFromInsertedModules(handle); mAudioFlinger.mPatchCommandThread->releaseAudioPatch(handle); mAfPatchPanelCallback->getPatchCommandThread()->releaseAudioPatch(handle); } /* List connected audio ports and they attributes */ Loading Loading @@ -904,12 +907,12 @@ void PatchPanel::notifyStreamClosed(audio_io_handle_t stream) AudioHwDevice* PatchPanel::findAudioHwDeviceByModule(audio_module_handle_t module) { if (module == AUDIO_MODULE_HANDLE_NONE) return nullptr; ssize_t index = mAudioFlinger.mAudioHwDevs.indexOfKey(module); ssize_t index = mAfPatchPanelCallback->getAudioHwDevs_l().indexOfKey(module); if (index < 0) { ALOGW("%s() bad hw module %d", __func__, module); return nullptr; } return mAudioFlinger.mAudioHwDevs.valueAt(index); return mAfPatchPanelCallback->getAudioHwDevs_l().valueAt(index); } sp<DeviceHalInterface> PatchPanel::findHwDeviceByModule(audio_module_handle_t module) Loading @@ -924,7 +927,7 @@ void PatchPanel::addSoftwarePatchToInsertedModules( { mInsertedModules[module].sw_patches.insert(handle); if (!mInsertedModules[module].streams.empty()) { mAudioFlinger.updateDownStreamPatches_l(patch, mInsertedModules[module].streams); mAfPatchPanelCallback->updateDownStreamPatches_l(patch, mInsertedModules[module].streams); } } Loading services/audioflinger/PatchPanel.h +3 −2 Original line number Diff line number Diff line Loading @@ -21,7 +21,8 @@ namespace android { class PatchPanel : public IAfPatchPanel { public: explicit PatchPanel(AudioFlinger* audioFlinger) : mAudioFlinger(*audioFlinger) {} explicit PatchPanel(const sp<IAfPatchPanelCallback>& afPatchPanelCallback) : mAfPatchPanelCallback(afPatchPanelCallback) {} /* List connected audio ports and their attributes */ status_t listAudioPorts(unsigned int *num_ports, Loading Loading @@ -71,7 +72,7 @@ private: void removeSoftwarePatchFromInsertedModules(audio_patch_handle_t handle); void erasePatch(audio_patch_handle_t handle); AudioFlinger &mAudioFlinger; const sp<IAfPatchPanelCallback> mAfPatchPanelCallback; std::map<audio_patch_handle_t, Patch> mPatches; // This map allows going from a thread to "downstream" software patches Loading Loading
services/audioflinger/AudioFlinger.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -412,6 +412,7 @@ void AudioFlinger::onFirstRef() mAAudioHwBurstMinMicros = getAAudioHardwareBurstMinUsecFromSystemProperty(); } mPatchPanel = IAfPatchPanel::create(sp<IAfPatchPanelCallback>::fromExisting(this)); mMelReporter = sp<MelReporter>::make(sp<IAfMelReporterCallback>::fromExisting(this)); } Loading
services/audioflinger/AudioFlinger.h +40 −34 Original line number Diff line number Diff line Loading @@ -167,10 +167,10 @@ class AudioFlinger , public IAfClientCallback , public IAfDeviceEffectManagerCallback , public IAfMelReporterCallback , public IAfPatchPanelCallback { friend class sp<AudioFlinger>; // TODO(b/291319167) Create interface and remove friends. friend class PatchPanel; // TODO(b/291012167) replace the Thread friends with an interface. friend class DirectOutputThread; friend class MixerThread; Loading Loading @@ -375,7 +375,7 @@ public: // ---- begin IAfDeviceEffectManagerCallback interface bool isAudioPolicyReady() const final { return mAudioPolicyReady.load(); } // below also used by IAfMelReporterCallback // below also used by IAfMelReporterCallback, IAfPatchPanelCallback const sp<PatchCommandThread>& getPatchCommandThread() final { return mPatchCommandThread; } status_t addEffectToHal( const struct audio_port_config* device, const sp<EffectHalInterface>& effect) final; Loading @@ -391,6 +391,41 @@ public: // ---- end of IAfMelReporterCallback interface // ---- begin IAfPatchPanelCallback interface void closeThreadInternal_l(const sp<IAfPlaybackThread>& thread) final; void closeThreadInternal_l(const sp<IAfRecordThread>& thread) final; // return thread associated with primary hardware device, or NULL IAfPlaybackThread* primaryPlaybackThread_l() const final; IAfPlaybackThread* checkPlaybackThread_l(audio_io_handle_t output) const final; IAfRecordThread* checkRecordThread_l(audio_io_handle_t input) const final; IAfMmapThread* checkMmapThread_l(audio_io_handle_t io) const final; void lock() const final ACQUIRE(mLock) { mLock.lock(); } void unlock() const final RELEASE(mLock) { mLock.unlock(); } sp<IAfThreadBase> openInput_l(audio_module_handle_t module, audio_io_handle_t* input, audio_config_t* config, audio_devices_t device, const char* address, audio_source_t source, audio_input_flags_t flags, audio_devices_t outputDevice, const String8& outputDeviceAddress) final; sp<IAfThreadBase> openOutput_l(audio_module_handle_t module, audio_io_handle_t* output, audio_config_t* halConfig, audio_config_base_t* mixerConfig, audio_devices_t deviceType, const String8& address, audio_output_flags_t flags) final; const DefaultKeyedVector<audio_module_handle_t, AudioHwDevice*>& getAudioHwDevs_l() const final { return mAudioHwDevs; } void updateDownStreamPatches_l(const struct audio_patch* patch, const std::set<audio_io_handle_t>& streams) final; void updateOutDevicesForRecordThreads_l(const DeviceDescriptorBaseVector& devices) final; // ---- end of IAfPatchPanelCallback interface /* List available audio ports and their attributes */ status_t listAudioPorts(unsigned int* num_ports, struct audio_port* ports) const; Loading @@ -412,9 +447,6 @@ public: const sp<os::ExternalVibration>& externalVibration); static void onExternalVibrationStop(const sp<os::ExternalVibration>& externalVibration); void updateDownStreamPatches_l(const struct audio_patch *patch, const std::set<audio_io_handle_t>& streams); std::optional<media::AudioVibratorInfo> getDefaultVibratorInfo_l(); private: Loading Loading @@ -454,9 +486,6 @@ public: bool btNrecIsOff() const { return mBtNrecIsOff.load(); } void lock() ACQUIRE(mLock) { mLock.lock(); } void unlock() RELEASE(mLock) { mLock.unlock(); } private: audio_mode_t getMode() const { return mMode; } Loading Loading @@ -628,29 +657,11 @@ private: } IAfThreadBase* checkThread_l(audio_io_handle_t ioHandle) const; IAfPlaybackThread* checkPlaybackThread_l(audio_io_handle_t output) const; IAfPlaybackThread* checkMixerThread_l(audio_io_handle_t output) const; IAfRecordThread* checkRecordThread_l(audio_io_handle_t input) const; IAfMmapThread* checkMmapThread_l(audio_io_handle_t io) const; sp<VolumeInterface> getVolumeInterface_l(audio_io_handle_t output) const; std::vector<sp<VolumeInterface>> getAllVolumeInterfaces_l() const; sp<IAfThreadBase> openInput_l(audio_module_handle_t module, audio_io_handle_t *input, audio_config_t *config, audio_devices_t device, const char* address, audio_source_t source, audio_input_flags_t flags, audio_devices_t outputDevice, const String8& outputDeviceAddress); sp<IAfThreadBase> openOutput_l(audio_module_handle_t module, audio_io_handle_t *output, audio_config_t *halConfig, audio_config_base_t *mixerConfig, audio_devices_t deviceType, const String8& address, audio_output_flags_t flags); void closeOutputFinish(const sp<IAfPlaybackThread>& thread); void closeInputFinish(const sp<IAfRecordThread>& thread); Loading @@ -675,14 +686,13 @@ private: // Thus it may fail by returning an ID of the wrong sign, // or by returning a non-unique ID. // This is the internal API. For the binder API see newAudioUniqueId(). // used by IAfDeviceEffectManagerCallback // used by IAfDeviceEffectManagerCallback, IAfPatchPanelCallback audio_unique_id_t nextUniqueId(audio_unique_id_use_t use) final; status_t moveEffectChain_l(audio_session_t sessionId, IAfPlaybackThread* srcThread, IAfPlaybackThread* dstThread); // return thread associated with primary hardware device, or NULL IAfPlaybackThread* primaryPlaybackThread_l() const; DeviceTypeSet primaryOutputDevice_l() const; // return the playback thread with smallest HAL buffer size, and prefer fast Loading Loading @@ -726,7 +736,6 @@ private: std::vector< sp<IAfEffectModule> > purgeStaleEffects_l(); void broadcastParametersToRecordThreads_l(const String8& keyValuePairs); void updateOutDevicesForRecordThreads_l(const DeviceDescriptorBaseVector& devices); void forwardParametersToDownstreamPatches_l( audio_io_handle_t upStream, const String8& keyValuePairs, const std::function<bool(const sp<IAfPlaybackThread>&)>& useThread = nullptr); Loading Loading @@ -844,9 +853,7 @@ private: // for use from destructor status_t closeOutput_nonvirtual(audio_io_handle_t output); void closeThreadInternal_l(const sp<IAfPlaybackThread>& thread); status_t closeInput_nonvirtual(audio_io_handle_t input); void closeThreadInternal_l(const sp<IAfRecordThread>& thread); void setAudioHwSyncForSession_l(IAfPlaybackThread* thread, audio_session_t sessionId); status_t checkStreamType(audio_stream_type_t stream) const; Loading @@ -873,8 +880,7 @@ private: nsecs_t mGlobalEffectEnableTime; // when a global effect was last enabled // protected by mLock const sp<IAfPatchPanel> mPatchPanel = IAfPatchPanel::create(this); /* const */ sp<IAfPatchPanel> mPatchPanel; public: // TODO(b/291319167) access by getter. Loading
services/audioflinger/IAfPatchPanel.h +38 −1 Original line number Diff line number Diff line Loading @@ -18,12 +18,14 @@ namespace android { class IAfMmapThread; class IAfPatchPanel; class IAfPatchRecord; class IAfPatchTrack; class IAfPlaybackThread; class IAfRecordThread; class IAfThreadBase; class PatchCommandThread; class SoftwarePatch { public: Loading Loading @@ -51,9 +53,44 @@ private: const audio_io_handle_t mRecordThreadHandle; }; class IAfPatchPanelCallback : public virtual RefBase { public: virtual void closeThreadInternal_l(const sp<IAfPlaybackThread>& thread) = 0; virtual void closeThreadInternal_l(const sp<IAfRecordThread>& thread) = 0; virtual IAfPlaybackThread* primaryPlaybackThread_l() const = 0; virtual IAfPlaybackThread* checkPlaybackThread_l(audio_io_handle_t output) const = 0; virtual IAfRecordThread* checkRecordThread_l(audio_io_handle_t input) const = 0; virtual IAfMmapThread* checkMmapThread_l(audio_io_handle_t io) const = 0; virtual sp<IAfThreadBase> openInput_l(audio_module_handle_t module, audio_io_handle_t* input, audio_config_t* config, audio_devices_t device, const char* address, audio_source_t source, audio_input_flags_t flags, audio_devices_t outputDevice, const String8& outputDeviceAddress) = 0; virtual sp<IAfThreadBase> openOutput_l(audio_module_handle_t module, audio_io_handle_t* output, audio_config_t* halConfig, audio_config_base_t* mixerConfig, audio_devices_t deviceType, const String8& address, audio_output_flags_t flags) = 0; virtual void lock() const = 0; virtual void unlock() const = 0; virtual const DefaultKeyedVector<audio_module_handle_t, AudioHwDevice*>& getAudioHwDevs_l() const = 0; virtual audio_unique_id_t nextUniqueId(audio_unique_id_use_t use) = 0; virtual const sp<PatchCommandThread>& getPatchCommandThread() = 0; virtual void updateDownStreamPatches_l( const struct audio_patch* patch, const std::set<audio_io_handle_t>& streams) = 0; virtual void updateOutDevicesForRecordThreads_l(const DeviceDescriptorBaseVector& devices) = 0; }; class IAfPatchPanel : public virtual RefBase { public: static sp<IAfPatchPanel> create(AudioFlinger* audioFlinger); static sp<IAfPatchPanel> create(const sp<IAfPatchPanelCallback>& afPatchPanelCallback); // Extraction of inner Endpoint and Patch classes would require interfaces // (in the Endpoint case a templated interface) but that seems Loading
services/audioflinger/PatchPanel.cpp +39 −36 Original line number Diff line number Diff line Loading @@ -96,8 +96,8 @@ status_t AudioFlinger::listAudioPatches( } /* static */ sp<IAfPatchPanel> IAfPatchPanel::create(AudioFlinger* audioFlinger) { return sp<PatchPanel>::make(audioFlinger); sp<IAfPatchPanel> IAfPatchPanel::create(const sp<IAfPatchPanelCallback>& afPatchPanelCallback) { return sp<PatchPanel>::make(afPatchPanelCallback); } status_t SoftwarePatch::getLatencyMs_l(double* latencyMs) const { Loading @@ -119,10 +119,10 @@ void PatchPanel::closeThreadInternal_l(const sp<IAfThreadBase>& thread) const { if (const auto recordThread = thread->asIAfRecordThread(); recordThread) { mAudioFlinger.closeThreadInternal_l(recordThread); mAfPatchPanelCallback->closeThreadInternal_l(recordThread); } else if (const auto playbackThread = thread->asIAfPlaybackThread(); playbackThread) { mAudioFlinger.closeThreadInternal_l(playbackThread); mAfPatchPanelCallback->closeThreadInternal_l(playbackThread); } else { LOG_ALWAYS_FATAL("%s: Endpoints only accept IAfPlayback and IAfRecord threads, " "invalid thread, id: %d type: %d", Loading Loading @@ -275,8 +275,8 @@ status_t PatchPanel::createAudioPatch(const struct audio_patch* patch, status = INVALID_OPERATION; goto exit; } const sp<IAfThreadBase> thread = mAudioFlinger.checkPlaybackThread_l(patch->sources[1].ext.mix.handle); const sp<IAfThreadBase> thread = mAfPatchPanelCallback->checkPlaybackThread_l( patch->sources[1].ext.mix.handle); if (thread == 0) { ALOGW("%s() cannot get playback thread", __func__); status = INVALID_OPERATION; Loading @@ -302,7 +302,7 @@ status_t PatchPanel::createAudioPatch(const struct audio_patch* patch, if (patch->sinks[0].config_mask & AUDIO_PORT_CONFIG_FLAGS) { flags = patch->sinks[0].flags.output; } const sp<IAfThreadBase> thread = mAudioFlinger.openOutput_l( const sp<IAfThreadBase> thread = mAfPatchPanelCallback->openOutput_l( patch->sinks[0].ext.device.hw_module, &output, &config, Loading @@ -310,7 +310,7 @@ status_t PatchPanel::createAudioPatch(const struct audio_patch* patch, outputDevice, outputDeviceAddress, flags); ALOGV("mAudioFlinger.openOutput_l() returned %p", thread.get()); ALOGV("mAfPatchPanelCallback->openOutput_l() returned %p", thread.get()); if (thread == 0) { status = NO_MEMORY; goto exit; Loading Loading @@ -349,7 +349,7 @@ status_t PatchPanel::createAudioPatch(const struct audio_patch* patch, == AUDIO_STREAM_VOICE_CALL) { source = AUDIO_SOURCE_VOICE_COMMUNICATION; } const sp<IAfThreadBase> thread = mAudioFlinger.openInput_l(srcModule, const sp<IAfThreadBase> thread = mAfPatchPanelCallback->openInput_l(srcModule, &input, &config, device, Loading @@ -358,7 +358,7 @@ status_t PatchPanel::createAudioPatch(const struct audio_patch* patch, flags, outputDevice, outputDeviceAddress); ALOGV("mAudioFlinger.openInput_l() returned %p inChannelMask %08x", ALOGV("mAfPatchPanelCallback->openInput_l() returned %p inChannelMask %08x", thread.get(), config.channel_mask); if (thread == 0) { status = NO_MEMORY; Loading @@ -374,10 +374,11 @@ status_t PatchPanel::createAudioPatch(const struct audio_patch* patch, } } else { if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) { sp<IAfThreadBase> thread = mAudioFlinger.checkRecordThread_l( sp<IAfThreadBase> thread = mAfPatchPanelCallback->checkRecordThread_l( patch->sinks[0].ext.mix.handle); if (thread == 0) { thread = mAudioFlinger.checkMmapThread_l(patch->sinks[0].ext.mix.handle); thread = mAfPatchPanelCallback->checkMmapThread_l( patch->sinks[0].ext.mix.handle); if (thread == 0) { ALOGW("%s() bad capture I/O handle %d", __func__, patch->sinks[0].ext.mix.handle); Loading @@ -385,9 +386,9 @@ status_t PatchPanel::createAudioPatch(const struct audio_patch* patch, goto exit; } } mAudioFlinger.unlock(); mAfPatchPanelCallback->unlock(); status = thread->sendCreateAudioPatchConfigEvent(patch, &halHandle); mAudioFlinger.lock(); mAfPatchPanelCallback->lock(); if (status == NO_ERROR) { newPatch.setThread(thread); } Loading @@ -411,7 +412,7 @@ status_t PatchPanel::createAudioPatch(const struct audio_patch* patch, } break; case AUDIO_PORT_TYPE_MIX: { audio_module_handle_t srcModule = patch->sources[0].ext.mix.hw_module; ssize_t index = mAudioFlinger.mAudioHwDevs.indexOfKey(srcModule); ssize_t index = mAfPatchPanelCallback->getAudioHwDevs_l().indexOfKey(srcModule); if (index < 0) { ALOGW("%s() bad src hw module %d", __func__, srcModule); status = BAD_VALUE; Loading @@ -437,10 +438,11 @@ status_t PatchPanel::createAudioPatch(const struct audio_patch* patch, device->applyAudioPortConfig(&patch->sinks[i]); devices.push_back(device); } sp<IAfThreadBase> thread = mAudioFlinger.checkPlaybackThread_l(patch->sources[0].ext.mix.handle); sp<IAfThreadBase> thread = mAfPatchPanelCallback->checkPlaybackThread_l( patch->sources[0].ext.mix.handle); if (thread == 0) { thread = mAudioFlinger.checkMmapThread_l(patch->sources[0].ext.mix.handle); thread = mAfPatchPanelCallback->checkMmapThread_l( patch->sources[0].ext.mix.handle); if (thread == 0) { ALOGW("%s() bad playback I/O handle %d", __func__, patch->sources[0].ext.mix.handle); Loading @@ -448,13 +450,13 @@ status_t PatchPanel::createAudioPatch(const struct audio_patch* patch, goto exit; } } if (thread == mAudioFlinger.primaryPlaybackThread_l()) { mAudioFlinger.updateOutDevicesForRecordThreads_l(devices); if (thread == mAfPatchPanelCallback->primaryPlaybackThread_l()) { mAfPatchPanelCallback->updateOutDevicesForRecordThreads_l(devices); } mAudioFlinger.unlock(); mAfPatchPanelCallback->unlock(); status = thread->sendCreateAudioPatchConfigEvent(patch, &halHandle); mAudioFlinger.lock(); mAfPatchPanelCallback->lock(); if (status == NO_ERROR) { newPatch.setThread(thread); } Loading @@ -479,9 +481,10 @@ status_t PatchPanel::createAudioPatch(const struct audio_patch* patch, exit: ALOGV("%s() status %d", __func__, status); if (status == NO_ERROR) { *handle = (audio_patch_handle_t) mAudioFlinger.nextUniqueId(AUDIO_UNIQUE_ID_USE_PATCH); *handle = static_cast<audio_patch_handle_t>( mAfPatchPanelCallback->nextUniqueId(AUDIO_UNIQUE_ID_USE_PATCH)); newPatch.mHalHandle = halHandle; mAudioFlinger.mPatchCommandThread->createAudioPatch(*handle, newPatch); mAfPatchPanelCallback->getPatchCommandThread()->createAudioPatch(*handle, newPatch); if (insertedModule != AUDIO_MODULE_HANDLE_NONE) { addSoftwarePatchToInsertedModules(insertedModule, *handle, &newPatch.mAudioPatch); } Loading Loading @@ -793,18 +796,18 @@ status_t PatchPanel::releaseAudioPatch(audio_patch_handle_t handle) if (patch.sinks[0].type == AUDIO_PORT_TYPE_MIX) { audio_io_handle_t ioHandle = patch.sinks[0].ext.mix.handle; sp<IAfThreadBase> thread = mAudioFlinger.checkRecordThread_l(ioHandle); sp<IAfThreadBase> thread = mAfPatchPanelCallback->checkRecordThread_l(ioHandle); if (thread == 0) { thread = mAudioFlinger.checkMmapThread_l(ioHandle); thread = mAfPatchPanelCallback->checkMmapThread_l(ioHandle); if (thread == 0) { ALOGW("%s() bad capture I/O handle %d", __func__, ioHandle); status = BAD_VALUE; break; } } mAudioFlinger.unlock(); mAfPatchPanelCallback->unlock(); status = thread->sendReleaseAudioPatchConfigEvent(removedPatch.mHalHandle); mAudioFlinger.lock(); mAfPatchPanelCallback->lock(); } else { status = hwDevice->releaseAudioPatch(removedPatch.mHalHandle); } Loading @@ -816,18 +819,18 @@ status_t PatchPanel::releaseAudioPatch(audio_patch_handle_t handle) break; } audio_io_handle_t ioHandle = src.ext.mix.handle; sp<IAfThreadBase> thread = mAudioFlinger.checkPlaybackThread_l(ioHandle); sp<IAfThreadBase> thread = mAfPatchPanelCallback->checkPlaybackThread_l(ioHandle); if (thread == 0) { thread = mAudioFlinger.checkMmapThread_l(ioHandle); thread = mAfPatchPanelCallback->checkMmapThread_l(ioHandle); if (thread == 0) { ALOGW("%s() bad playback I/O handle %d", __func__, ioHandle); status = BAD_VALUE; break; } } mAudioFlinger.unlock(); mAfPatchPanelCallback->unlock(); status = thread->sendReleaseAudioPatchConfigEvent(removedPatch.mHalHandle); mAudioFlinger.lock(); mAfPatchPanelCallback->lock(); } break; default: status = BAD_VALUE; Loading @@ -840,7 +843,7 @@ status_t PatchPanel::releaseAudioPatch(audio_patch_handle_t handle) void PatchPanel::erasePatch(audio_patch_handle_t handle) { mPatches.erase(handle); removeSoftwarePatchFromInsertedModules(handle); mAudioFlinger.mPatchCommandThread->releaseAudioPatch(handle); mAfPatchPanelCallback->getPatchCommandThread()->releaseAudioPatch(handle); } /* List connected audio ports and they attributes */ Loading Loading @@ -904,12 +907,12 @@ void PatchPanel::notifyStreamClosed(audio_io_handle_t stream) AudioHwDevice* PatchPanel::findAudioHwDeviceByModule(audio_module_handle_t module) { if (module == AUDIO_MODULE_HANDLE_NONE) return nullptr; ssize_t index = mAudioFlinger.mAudioHwDevs.indexOfKey(module); ssize_t index = mAfPatchPanelCallback->getAudioHwDevs_l().indexOfKey(module); if (index < 0) { ALOGW("%s() bad hw module %d", __func__, module); return nullptr; } return mAudioFlinger.mAudioHwDevs.valueAt(index); return mAfPatchPanelCallback->getAudioHwDevs_l().valueAt(index); } sp<DeviceHalInterface> PatchPanel::findHwDeviceByModule(audio_module_handle_t module) Loading @@ -924,7 +927,7 @@ void PatchPanel::addSoftwarePatchToInsertedModules( { mInsertedModules[module].sw_patches.insert(handle); if (!mInsertedModules[module].streams.empty()) { mAudioFlinger.updateDownStreamPatches_l(patch, mInsertedModules[module].streams); mAfPatchPanelCallback->updateDownStreamPatches_l(patch, mInsertedModules[module].streams); } } Loading
services/audioflinger/PatchPanel.h +3 −2 Original line number Diff line number Diff line Loading @@ -21,7 +21,8 @@ namespace android { class PatchPanel : public IAfPatchPanel { public: explicit PatchPanel(AudioFlinger* audioFlinger) : mAudioFlinger(*audioFlinger) {} explicit PatchPanel(const sp<IAfPatchPanelCallback>& afPatchPanelCallback) : mAfPatchPanelCallback(afPatchPanelCallback) {} /* List connected audio ports and their attributes */ status_t listAudioPorts(unsigned int *num_ports, Loading Loading @@ -71,7 +72,7 @@ private: void removeSoftwarePatchFromInsertedModules(audio_patch_handle_t handle); void erasePatch(audio_patch_handle_t handle); AudioFlinger &mAudioFlinger; const sp<IAfPatchPanelCallback> mAfPatchPanelCallback; std::map<audio_patch_handle_t, Patch> mPatches; // This map allows going from a thread to "downstream" software patches Loading