Loading services/audioflinger/AudioFlinger.cpp +5 −5 Original line number Diff line number Diff line Loading @@ -4563,7 +4563,7 @@ status_t AudioFlinger::listAudioPorts(unsigned int* num_ports, struct audio_port* ports) const { audio_utils::lock_guard _l(mutex()); return mPatchPanel->listAudioPorts(num_ports, ports); return mPatchPanel->listAudioPorts_l(num_ports, ports); } /* Get supported attributes for a given audio port */ Loading @@ -4574,7 +4574,7 @@ status_t AudioFlinger::getAudioPort(struct audio_port_v7* port) const { } audio_utils::lock_guard _l(mutex()); return mPatchPanel->getAudioPort(port); return mPatchPanel->getAudioPort_l(port); } /* Connect a patch between several source and sink ports */ Loading @@ -4587,14 +4587,14 @@ status_t AudioFlinger::createAudioPatch( } audio_utils::lock_guard _l(mutex()); return mPatchPanel->createAudioPatch(patch, handle); return mPatchPanel->createAudioPatch_l(patch, handle); } /* Disconnect a patch */ status_t AudioFlinger::releaseAudioPatch(audio_patch_handle_t handle) { audio_utils::lock_guard _l(mutex()); return mPatchPanel->releaseAudioPatch(handle); return mPatchPanel->releaseAudioPatch_l(handle); } /* List connected audio ports and they attributes */ Loading @@ -4602,7 +4602,7 @@ status_t AudioFlinger::listAudioPatches( unsigned int* num_patches, struct audio_patch* patches) const { audio_utils::lock_guard _l(mutex()); return mPatchPanel->listAudioPatches(num_patches, patches); return mPatchPanel->listAudioPatches_l(num_patches, patches); } // ---------------------------------------------------------------------------- Loading services/audioflinger/IAfPatchPanel.h +44 −29 Original line number Diff line number Diff line Loading @@ -45,8 +45,7 @@ public: mRecordThreadHandle(recordThreadHandle) {} SoftwarePatch(const SoftwarePatch&) = default; // Must be called under AudioFlinger::mLock status_t getLatencyMs_l(double* latencyMs) const; status_t getLatencyMs_l(double* latencyMs) const REQUIRES(audio_utils::AudioFlinger_Mutex); audio_patch_handle_t getPatchHandle() const { return mPatchHandle; }; audio_io_handle_t getPlaybackThreadHandle() const { return mPlaybackThreadHandle; }; audio_io_handle_t getRecordThreadHandle() const { return mRecordThreadHandle; }; Loading @@ -60,12 +59,14 @@ private: 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 void closeThreadInternal_l(const sp<IAfPlaybackThread>& thread) REQUIRES(mutex()) = 0; virtual void closeThreadInternal_l(const sp<IAfRecordThread>& thread) REQUIRES(mutex()) = 0; virtual IAfPlaybackThread* primaryPlaybackThread_l() const REQUIRES(mutex()) = 0; virtual IAfPlaybackThread* checkPlaybackThread_l(audio_io_handle_t output) const REQUIRES(mutex()) = 0; virtual IAfRecordThread* checkRecordThread_l(audio_io_handle_t input) const REQUIRES(mutex()) = 0; virtual IAfMmapThread* checkMmapThread_l(audio_io_handle_t io) const REQUIRES(mutex()) = 0; virtual sp<IAfThreadBase> openInput_l(audio_module_handle_t module, audio_io_handle_t* input, audio_config_t* config, Loading @@ -74,22 +75,25 @@ public: audio_source_t source, audio_input_flags_t flags, audio_devices_t outputDevice, const String8& outputDeviceAddress) = 0; const String8& outputDeviceAddress) REQUIRES(mutex()) = 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 audio_utils::mutex& mutex() const = 0; audio_output_flags_t flags) REQUIRES(mutex()) = 0; virtual audio_utils::mutex& mutex() const RETURN_CAPABILITY(audio_utils::AudioFlinger_Mutex) = 0; virtual const DefaultKeyedVector<audio_module_handle_t, AudioHwDevice*>& getAudioHwDevs_l() const = 0; getAudioHwDevs_l() const REQUIRES(mutex()) = 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; const struct audio_patch* patch, const std::set<audio_io_handle_t>& streams) REQUIRES(mutex()) = 0; virtual void updateOutDevicesForRecordThreads_l(const DeviceDescriptorBaseVector& devices) REQUIRES(mutex()) = 0; }; class IAfPatchPanel : public virtual RefBase { Loading Loading @@ -133,9 +137,12 @@ public: sp<const ThreadType> const_thread() const { return mThread; } sp<const TrackType> const_track() const { return mTrack; } void closeConnections(const sp<IAfPatchPanel>& panel) { void closeConnections_l(const sp<IAfPatchPanel>& panel) REQUIRES(audio_utils::AudioFlinger_Mutex) NO_THREAD_SAFETY_ANALYSIS // this is broken in clang { if (mHandle != AUDIO_PATCH_HANDLE_NONE) { panel->releaseAudioPatch(mHandle); panel->releaseAudioPatch_l(mHandle); mHandle = AUDIO_PATCH_HANDLE_NONE; } if (mThread != nullptr) { Loading Loading @@ -217,8 +224,10 @@ public: friend void swap(Patch& a, Patch& b) noexcept { a.swap(b); } status_t createConnections(const sp<IAfPatchPanel>& panel); void clearConnections(const sp<IAfPatchPanel>& panel); status_t createConnections_l(const sp<IAfPatchPanel>& panel) REQUIRES(audio_utils::AudioFlinger_Mutex); void clearConnections_l(const sp<IAfPatchPanel>& panel) REQUIRES(audio_utils::AudioFlinger_Mutex); bool isSoftware() const { return mRecord.handle() != AUDIO_PATCH_HANDLE_NONE || mPlayback.handle() != AUDIO_PATCH_HANDLE_NONE; Loading Loading @@ -250,22 +259,27 @@ public: }; /* List connected audio ports and their attributes */ virtual status_t listAudioPorts(unsigned int* num_ports, struct audio_port* ports) = 0; virtual status_t listAudioPorts_l(unsigned int* num_ports, struct audio_port* ports) REQUIRES(audio_utils::AudioFlinger_Mutex) = 0; /* Get supported attributes for a given audio port */ virtual status_t getAudioPort(struct audio_port_v7* port) = 0; virtual status_t getAudioPort_l(struct audio_port_v7* port) REQUIRES(audio_utils::AudioFlinger_Mutex) = 0; /* Create a patch between several source and sink ports */ virtual status_t createAudioPatch( virtual status_t createAudioPatch_l( const struct audio_patch* patch, audio_patch_handle_t* handle, bool endpointPatch = false) = 0; bool endpointPatch = false) REQUIRES(audio_utils::AudioFlinger_Mutex) = 0; /* Release a patch */ virtual status_t releaseAudioPatch(audio_patch_handle_t handle) = 0; virtual status_t releaseAudioPatch_l(audio_patch_handle_t handle) REQUIRES(audio_utils::AudioFlinger_Mutex) = 0; /* List connected audio devices and they attributes */ virtual status_t listAudioPatches(unsigned int* num_patches, struct audio_patch* patches) = 0; virtual status_t listAudioPatches_l(unsigned int* num_patches, struct audio_patch* patches) REQUIRES(audio_utils::AudioFlinger_Mutex) = 0; // Retrieves all currently estrablished software patches for a stream // opened on an intermediate module. Loading @@ -280,13 +294,14 @@ public: virtual void dump(int fd) const = 0; // Must be called under AudioFlinger::mLock virtual const std::map<audio_patch_handle_t, Patch>& patches_l() const REQUIRES(audio_utils::AudioFlinger_Mutex) = 0; virtual const std::map<audio_patch_handle_t, Patch>& patches_l() const = 0; virtual status_t getLatencyMs_l(audio_patch_handle_t patchHandle, double* latencyMs) const REQUIRES(audio_utils::AudioFlinger_Mutex) = 0; virtual status_t getLatencyMs_l(audio_patch_handle_t patchHandle, double* latencyMs) const = 0; virtual void closeThreadInternal_l(const sp<IAfThreadBase>& thread) const = 0; virtual void closeThreadInternal_l(const sp<IAfThreadBase>& thread) const REQUIRES(audio_utils::AudioFlinger_Mutex) = 0; }; } // namespace android services/audioflinger/PatchPanel.cpp +25 −25 Original line number Diff line number Diff line Loading @@ -83,7 +83,7 @@ void PatchPanel::closeThreadInternal_l(const sp<IAfThreadBase>& thread) const } /* List connected audio ports and their attributes */ status_t PatchPanel::listAudioPorts(unsigned int* /* num_ports */, status_t PatchPanel::listAudioPorts_l(unsigned int* /* num_ports */, struct audio_port *ports __unused) { ALOGV(__func__); Loading @@ -91,14 +91,14 @@ status_t PatchPanel::listAudioPorts(unsigned int* /* num_ports */, } /* Get supported attributes for a given audio port */ status_t PatchPanel::getAudioPort(struct audio_port_v7* port) status_t PatchPanel::getAudioPort_l(struct audio_port_v7* port) { if (port->type != AUDIO_PORT_TYPE_DEVICE) { // Only query the HAL when the port is a device. // TODO: implement getAudioPort for mix. return INVALID_OPERATION; } AudioHwDevice* hwDevice = findAudioHwDeviceByModule(port->ext.device.hw_module); AudioHwDevice* hwDevice = findAudioHwDeviceByModule_l(port->ext.device.hw_module); if (hwDevice == nullptr) { ALOGW("%s cannot find hw module %d", __func__, port->ext.device.hw_module); return BAD_VALUE; Loading @@ -110,7 +110,7 @@ status_t PatchPanel::getAudioPort(struct audio_port_v7* port) } /* Connect a patch between several source and sink ports */ status_t PatchPanel::createAudioPatch(const struct audio_patch* patch, status_t PatchPanel::createAudioPatch_l(const struct audio_patch* patch, audio_patch_handle_t *handle, bool endpointPatch) //unlocks AudioFlinger::mLock when calling IAfThreadBase::sendCreateAudioPatchConfigEvent Loading Loading @@ -144,7 +144,7 @@ status_t PatchPanel::createAudioPatch(const struct audio_patch* patch, // 1) if a software patch is present, release the playback and capture threads and // tracks created. This will also release the corresponding audio HAL patches if (removedPatch.isSoftware()) { removedPatch.clearConnections(this); removedPatch.clearConnections_l(this); } // 2) if the new patch and old patch source or sink are devices from different // hw modules, clear the audio HAL patches now because they will not be updated Loading @@ -169,7 +169,7 @@ status_t PatchPanel::createAudioPatch(const struct audio_patch* patch, // removedPatch.mHalHandle would be AUDIO_PATCH_HANDLE_NONE in this case. hwModule = oldPatch.sinks[0].ext.device.hw_module; } sp<DeviceHalInterface> hwDevice = findHwDeviceByModule(hwModule); sp<DeviceHalInterface> hwDevice = findHwDeviceByModule_l(hwModule); if (hwDevice != 0) { hwDevice->releaseAudioPatch(removedPatch.mHalHandle); } Loading @@ -185,7 +185,7 @@ status_t PatchPanel::createAudioPatch(const struct audio_patch* patch, switch (patch->sources[0].type) { case AUDIO_PORT_TYPE_DEVICE: { audio_module_handle_t srcModule = patch->sources[0].ext.device.hw_module; AudioHwDevice *audioHwDevice = findAudioHwDeviceByModule(srcModule); AudioHwDevice *audioHwDevice = findAudioHwDeviceByModule_l(srcModule); if (!audioHwDevice) { status = BAD_VALUE; goto exit; Loading Loading @@ -317,7 +317,7 @@ status_t PatchPanel::createAudioPatch(const struct audio_patch* patch, goto exit; } newPatch.mRecord.setThread(thread->asIAfRecordThread().get()); status = newPatch.createConnections(this); status = newPatch.createConnections_l(this); if (status != NO_ERROR) { goto exit; } Loading Loading @@ -438,11 +438,11 @@ exit: newPatch.mHalHandle = halHandle; mAfPatchPanelCallback->getPatchCommandThread()->createAudioPatch(*handle, newPatch); if (insertedModule != AUDIO_MODULE_HANDLE_NONE) { addSoftwarePatchToInsertedModules(insertedModule, *handle, &newPatch.mAudioPatch); addSoftwarePatchToInsertedModules_l(insertedModule, *handle, &newPatch.mAudioPatch); } mPatches.insert(std::make_pair(*handle, std::move(newPatch))); } else { newPatch.clearConnections(this); newPatch.clearConnections_l(this); } return status; } Loading @@ -453,10 +453,10 @@ PatchPanel::Patch::~Patch() mRecord.handle(), mPlayback.handle()); } status_t PatchPanel::Patch::createConnections(const sp<IAfPatchPanel>& panel) status_t PatchPanel::Patch::createConnections_l(const sp<IAfPatchPanel>& panel) { // create patch from source device to record thread input status_t status = panel->createAudioPatch( status_t status = panel->createAudioPatch_l( PatchBuilder().addSource(mAudioPatch.sources[0]). addSink(mRecord.thread(), { .source = AUDIO_SOURCE_MIC }).patch(), mRecord.handlePtr(), Loading @@ -468,7 +468,7 @@ status_t PatchPanel::Patch::createConnections(const sp<IAfPatchPanel>& panel) // create patch from playback thread output to sink device if (mAudioPatch.num_sinks != 0) { status = panel->createAudioPatch( status = panel->createAudioPatch_l( PatchBuilder().addSource(mPlayback.thread()).addSink(mAudioPatch.sinks[0]).patch(), mPlayback.handlePtr(), true /*endpointPatch*/); Loading Loading @@ -617,15 +617,15 @@ status_t PatchPanel::Patch::createConnections(const sp<IAfPatchPanel>& panel) return status; } void PatchPanel::Patch::clearConnections(const sp<IAfPatchPanel>& panel) void PatchPanel::Patch::clearConnections_l(const sp<IAfPatchPanel>& panel) { ALOGV("%s() mRecord.handle %d mPlayback.handle %d", __func__, mRecord.handle(), mPlayback.handle()); mRecord.stopTrack(); mPlayback.stopTrack(); mRecord.clearTrackPeer(); // mRecord stop is synchronous. Break PeerProxy sp<> cycle. mRecord.closeConnections(panel); mPlayback.closeConnections(panel); mRecord.closeConnections_l(panel); mPlayback.closeConnections_l(panel); } status_t PatchPanel::Patch::getLatencyMs(double* latencyMs) const Loading Loading @@ -715,7 +715,7 @@ String8 PatchPanel::Patch::dump(audio_patch_handle_t myHandle) const } /* Disconnect a patch */ status_t PatchPanel::releaseAudioPatch(audio_patch_handle_t handle) status_t PatchPanel::releaseAudioPatch_l(audio_patch_handle_t handle) //unlocks AudioFlinger::mLock when calling IAfThreadBase::sendReleaseAudioPatchConfigEvent //to avoid deadlocks if the thread loop needs to acquire AudioFlinger::mLock //before processing the release patch request. Loading @@ -734,7 +734,7 @@ status_t PatchPanel::releaseAudioPatch(audio_patch_handle_t handle) const struct audio_port_config &src = patch.sources[0]; switch (src.type) { case AUDIO_PORT_TYPE_DEVICE: { sp<DeviceHalInterface> hwDevice = findHwDeviceByModule(src.ext.device.hw_module); sp<DeviceHalInterface> hwDevice = findHwDeviceByModule_l(src.ext.device.hw_module); if (hwDevice == 0) { ALOGW("%s() bad src hw module %d", __func__, src.ext.device.hw_module); status = BAD_VALUE; Loading @@ -742,7 +742,7 @@ status_t PatchPanel::releaseAudioPatch(audio_patch_handle_t handle) } if (removedPatch.isSoftware()) { removedPatch.clearConnections(this); removedPatch.clearConnections_l(this); break; } Loading @@ -765,7 +765,7 @@ status_t PatchPanel::releaseAudioPatch(audio_patch_handle_t handle) } } break; case AUDIO_PORT_TYPE_MIX: { if (findHwDeviceByModule(src.ext.mix.hw_module) == 0) { if (findHwDeviceByModule_l(src.ext.mix.hw_module) == 0) { ALOGW("%s() bad src hw module %d", __func__, src.ext.mix.hw_module); status = BAD_VALUE; break; Loading Loading @@ -799,7 +799,7 @@ void PatchPanel::erasePatch(audio_patch_handle_t handle) { } /* List connected audio ports and they attributes */ status_t PatchPanel::listAudioPatches(unsigned int* /* num_patches */, status_t PatchPanel::listAudioPatches_l(unsigned int* /* num_patches */, struct audio_patch *patches __unused) { ALOGV(__func__); Loading Loading @@ -856,7 +856,7 @@ void PatchPanel::notifyStreamClosed(audio_io_handle_t stream) } } AudioHwDevice* PatchPanel::findAudioHwDeviceByModule(audio_module_handle_t module) AudioHwDevice* PatchPanel::findAudioHwDeviceByModule_l(audio_module_handle_t module) { if (module == AUDIO_MODULE_HANDLE_NONE) return nullptr; ssize_t index = mAfPatchPanelCallback->getAudioHwDevs_l().indexOfKey(module); Loading @@ -867,13 +867,13 @@ AudioHwDevice* PatchPanel::findAudioHwDeviceByModule(audio_module_handle_t modul return mAfPatchPanelCallback->getAudioHwDevs_l().valueAt(index); } sp<DeviceHalInterface> PatchPanel::findHwDeviceByModule(audio_module_handle_t module) sp<DeviceHalInterface> PatchPanel::findHwDeviceByModule_l(audio_module_handle_t module) { AudioHwDevice *audioHwDevice = findAudioHwDeviceByModule(module); AudioHwDevice *audioHwDevice = findAudioHwDeviceByModule_l(module); return audioHwDevice ? audioHwDevice->hwDevice() : nullptr; } void PatchPanel::addSoftwarePatchToInsertedModules( void PatchPanel::addSoftwarePatchToInsertedModules_l( audio_module_handle_t module, audio_patch_handle_t handle, const struct audio_patch *patch) { Loading services/audioflinger/PatchPanel.h +26 −18 Original line number Diff line number Diff line Loading @@ -30,25 +30,29 @@ public: : mAfPatchPanelCallback(afPatchPanelCallback) {} /* List connected audio ports and their attributes */ status_t listAudioPorts(unsigned int *num_ports, struct audio_port* ports) final; status_t listAudioPorts_l(unsigned int *num_ports, struct audio_port* ports) final REQUIRES(audio_utils::AudioFlinger_Mutex); /* Get supported attributes for a given audio port */ status_t getAudioPort(struct audio_port_v7* port) final; status_t getAudioPort_l(struct audio_port_v7* port) final REQUIRES(audio_utils::AudioFlinger_Mutex); /* Create a patch between several source and sink ports */ status_t createAudioPatch(const struct audio_patch *patch, status_t createAudioPatch_l(const struct audio_patch *patch, audio_patch_handle_t *handle, bool endpointPatch = false) final; bool endpointPatch = false) final REQUIRES(audio_utils::AudioFlinger_Mutex); /* Release a patch */ status_t releaseAudioPatch(audio_patch_handle_t handle) final; status_t releaseAudioPatch_l(audio_patch_handle_t handle) final REQUIRES(audio_utils::AudioFlinger_Mutex); /* List connected audio devices and they attributes */ status_t listAudioPatches(unsigned int *num_patches, struct audio_patch* patches) final; status_t listAudioPatches_l(unsigned int *num_patches, struct audio_patch* patches) final REQUIRES(audio_utils::AudioFlinger_Mutex); // Retrieves all currently estrablished software patches for a stream // Retrieves all currently established software patches for a stream // opened on an intermediate module. status_t getDownstreamSoftwarePatches(audio_io_handle_t stream, std::vector<SoftwarePatch>* patches) const final; Loading @@ -60,20 +64,24 @@ public: void dump(int fd) const final; // Call with AudioFlinger mLock held const std::map<audio_patch_handle_t, Patch>& patches_l() const final { return mPatches; } const std::map<audio_patch_handle_t, Patch>& patches_l() const final REQUIRES(audio_utils::AudioFlinger_Mutex) { return mPatches; } // Must be called under AudioFlinger::mLock status_t getLatencyMs_l(audio_patch_handle_t patchHandle, double* latencyMs) const final; status_t getLatencyMs_l(audio_patch_handle_t patchHandle, double* latencyMs) const final REQUIRES(audio_utils::AudioFlinger_Mutex); void closeThreadInternal_l(const sp<IAfThreadBase>& thread) const final; void closeThreadInternal_l(const sp<IAfThreadBase>& thread) const final REQUIRES(audio_utils::AudioFlinger_Mutex); private: AudioHwDevice* findAudioHwDeviceByModule(audio_module_handle_t module); sp<DeviceHalInterface> findHwDeviceByModule(audio_module_handle_t module); void addSoftwarePatchToInsertedModules( AudioHwDevice* findAudioHwDeviceByModule_l(audio_module_handle_t module) REQUIRES(audio_utils::AudioFlinger_Mutex); sp<DeviceHalInterface> findHwDeviceByModule_l(audio_module_handle_t module) REQUIRES(audio_utils::AudioFlinger_Mutex); void addSoftwarePatchToInsertedModules_l( audio_module_handle_t module, audio_patch_handle_t handle, const struct audio_patch *patch); const struct audio_patch *patch) REQUIRES(audio_utils::AudioFlinger_Mutex); void removeSoftwarePatchFromInsertedModules(audio_patch_handle_t handle); void erasePatch(audio_patch_handle_t handle); Loading Loading
services/audioflinger/AudioFlinger.cpp +5 −5 Original line number Diff line number Diff line Loading @@ -4563,7 +4563,7 @@ status_t AudioFlinger::listAudioPorts(unsigned int* num_ports, struct audio_port* ports) const { audio_utils::lock_guard _l(mutex()); return mPatchPanel->listAudioPorts(num_ports, ports); return mPatchPanel->listAudioPorts_l(num_ports, ports); } /* Get supported attributes for a given audio port */ Loading @@ -4574,7 +4574,7 @@ status_t AudioFlinger::getAudioPort(struct audio_port_v7* port) const { } audio_utils::lock_guard _l(mutex()); return mPatchPanel->getAudioPort(port); return mPatchPanel->getAudioPort_l(port); } /* Connect a patch between several source and sink ports */ Loading @@ -4587,14 +4587,14 @@ status_t AudioFlinger::createAudioPatch( } audio_utils::lock_guard _l(mutex()); return mPatchPanel->createAudioPatch(patch, handle); return mPatchPanel->createAudioPatch_l(patch, handle); } /* Disconnect a patch */ status_t AudioFlinger::releaseAudioPatch(audio_patch_handle_t handle) { audio_utils::lock_guard _l(mutex()); return mPatchPanel->releaseAudioPatch(handle); return mPatchPanel->releaseAudioPatch_l(handle); } /* List connected audio ports and they attributes */ Loading @@ -4602,7 +4602,7 @@ status_t AudioFlinger::listAudioPatches( unsigned int* num_patches, struct audio_patch* patches) const { audio_utils::lock_guard _l(mutex()); return mPatchPanel->listAudioPatches(num_patches, patches); return mPatchPanel->listAudioPatches_l(num_patches, patches); } // ---------------------------------------------------------------------------- Loading
services/audioflinger/IAfPatchPanel.h +44 −29 Original line number Diff line number Diff line Loading @@ -45,8 +45,7 @@ public: mRecordThreadHandle(recordThreadHandle) {} SoftwarePatch(const SoftwarePatch&) = default; // Must be called under AudioFlinger::mLock status_t getLatencyMs_l(double* latencyMs) const; status_t getLatencyMs_l(double* latencyMs) const REQUIRES(audio_utils::AudioFlinger_Mutex); audio_patch_handle_t getPatchHandle() const { return mPatchHandle; }; audio_io_handle_t getPlaybackThreadHandle() const { return mPlaybackThreadHandle; }; audio_io_handle_t getRecordThreadHandle() const { return mRecordThreadHandle; }; Loading @@ -60,12 +59,14 @@ private: 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 void closeThreadInternal_l(const sp<IAfPlaybackThread>& thread) REQUIRES(mutex()) = 0; virtual void closeThreadInternal_l(const sp<IAfRecordThread>& thread) REQUIRES(mutex()) = 0; virtual IAfPlaybackThread* primaryPlaybackThread_l() const REQUIRES(mutex()) = 0; virtual IAfPlaybackThread* checkPlaybackThread_l(audio_io_handle_t output) const REQUIRES(mutex()) = 0; virtual IAfRecordThread* checkRecordThread_l(audio_io_handle_t input) const REQUIRES(mutex()) = 0; virtual IAfMmapThread* checkMmapThread_l(audio_io_handle_t io) const REQUIRES(mutex()) = 0; virtual sp<IAfThreadBase> openInput_l(audio_module_handle_t module, audio_io_handle_t* input, audio_config_t* config, Loading @@ -74,22 +75,25 @@ public: audio_source_t source, audio_input_flags_t flags, audio_devices_t outputDevice, const String8& outputDeviceAddress) = 0; const String8& outputDeviceAddress) REQUIRES(mutex()) = 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 audio_utils::mutex& mutex() const = 0; audio_output_flags_t flags) REQUIRES(mutex()) = 0; virtual audio_utils::mutex& mutex() const RETURN_CAPABILITY(audio_utils::AudioFlinger_Mutex) = 0; virtual const DefaultKeyedVector<audio_module_handle_t, AudioHwDevice*>& getAudioHwDevs_l() const = 0; getAudioHwDevs_l() const REQUIRES(mutex()) = 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; const struct audio_patch* patch, const std::set<audio_io_handle_t>& streams) REQUIRES(mutex()) = 0; virtual void updateOutDevicesForRecordThreads_l(const DeviceDescriptorBaseVector& devices) REQUIRES(mutex()) = 0; }; class IAfPatchPanel : public virtual RefBase { Loading Loading @@ -133,9 +137,12 @@ public: sp<const ThreadType> const_thread() const { return mThread; } sp<const TrackType> const_track() const { return mTrack; } void closeConnections(const sp<IAfPatchPanel>& panel) { void closeConnections_l(const sp<IAfPatchPanel>& panel) REQUIRES(audio_utils::AudioFlinger_Mutex) NO_THREAD_SAFETY_ANALYSIS // this is broken in clang { if (mHandle != AUDIO_PATCH_HANDLE_NONE) { panel->releaseAudioPatch(mHandle); panel->releaseAudioPatch_l(mHandle); mHandle = AUDIO_PATCH_HANDLE_NONE; } if (mThread != nullptr) { Loading Loading @@ -217,8 +224,10 @@ public: friend void swap(Patch& a, Patch& b) noexcept { a.swap(b); } status_t createConnections(const sp<IAfPatchPanel>& panel); void clearConnections(const sp<IAfPatchPanel>& panel); status_t createConnections_l(const sp<IAfPatchPanel>& panel) REQUIRES(audio_utils::AudioFlinger_Mutex); void clearConnections_l(const sp<IAfPatchPanel>& panel) REQUIRES(audio_utils::AudioFlinger_Mutex); bool isSoftware() const { return mRecord.handle() != AUDIO_PATCH_HANDLE_NONE || mPlayback.handle() != AUDIO_PATCH_HANDLE_NONE; Loading Loading @@ -250,22 +259,27 @@ public: }; /* List connected audio ports and their attributes */ virtual status_t listAudioPorts(unsigned int* num_ports, struct audio_port* ports) = 0; virtual status_t listAudioPorts_l(unsigned int* num_ports, struct audio_port* ports) REQUIRES(audio_utils::AudioFlinger_Mutex) = 0; /* Get supported attributes for a given audio port */ virtual status_t getAudioPort(struct audio_port_v7* port) = 0; virtual status_t getAudioPort_l(struct audio_port_v7* port) REQUIRES(audio_utils::AudioFlinger_Mutex) = 0; /* Create a patch between several source and sink ports */ virtual status_t createAudioPatch( virtual status_t createAudioPatch_l( const struct audio_patch* patch, audio_patch_handle_t* handle, bool endpointPatch = false) = 0; bool endpointPatch = false) REQUIRES(audio_utils::AudioFlinger_Mutex) = 0; /* Release a patch */ virtual status_t releaseAudioPatch(audio_patch_handle_t handle) = 0; virtual status_t releaseAudioPatch_l(audio_patch_handle_t handle) REQUIRES(audio_utils::AudioFlinger_Mutex) = 0; /* List connected audio devices and they attributes */ virtual status_t listAudioPatches(unsigned int* num_patches, struct audio_patch* patches) = 0; virtual status_t listAudioPatches_l(unsigned int* num_patches, struct audio_patch* patches) REQUIRES(audio_utils::AudioFlinger_Mutex) = 0; // Retrieves all currently estrablished software patches for a stream // opened on an intermediate module. Loading @@ -280,13 +294,14 @@ public: virtual void dump(int fd) const = 0; // Must be called under AudioFlinger::mLock virtual const std::map<audio_patch_handle_t, Patch>& patches_l() const REQUIRES(audio_utils::AudioFlinger_Mutex) = 0; virtual const std::map<audio_patch_handle_t, Patch>& patches_l() const = 0; virtual status_t getLatencyMs_l(audio_patch_handle_t patchHandle, double* latencyMs) const REQUIRES(audio_utils::AudioFlinger_Mutex) = 0; virtual status_t getLatencyMs_l(audio_patch_handle_t patchHandle, double* latencyMs) const = 0; virtual void closeThreadInternal_l(const sp<IAfThreadBase>& thread) const = 0; virtual void closeThreadInternal_l(const sp<IAfThreadBase>& thread) const REQUIRES(audio_utils::AudioFlinger_Mutex) = 0; }; } // namespace android
services/audioflinger/PatchPanel.cpp +25 −25 Original line number Diff line number Diff line Loading @@ -83,7 +83,7 @@ void PatchPanel::closeThreadInternal_l(const sp<IAfThreadBase>& thread) const } /* List connected audio ports and their attributes */ status_t PatchPanel::listAudioPorts(unsigned int* /* num_ports */, status_t PatchPanel::listAudioPorts_l(unsigned int* /* num_ports */, struct audio_port *ports __unused) { ALOGV(__func__); Loading @@ -91,14 +91,14 @@ status_t PatchPanel::listAudioPorts(unsigned int* /* num_ports */, } /* Get supported attributes for a given audio port */ status_t PatchPanel::getAudioPort(struct audio_port_v7* port) status_t PatchPanel::getAudioPort_l(struct audio_port_v7* port) { if (port->type != AUDIO_PORT_TYPE_DEVICE) { // Only query the HAL when the port is a device. // TODO: implement getAudioPort for mix. return INVALID_OPERATION; } AudioHwDevice* hwDevice = findAudioHwDeviceByModule(port->ext.device.hw_module); AudioHwDevice* hwDevice = findAudioHwDeviceByModule_l(port->ext.device.hw_module); if (hwDevice == nullptr) { ALOGW("%s cannot find hw module %d", __func__, port->ext.device.hw_module); return BAD_VALUE; Loading @@ -110,7 +110,7 @@ status_t PatchPanel::getAudioPort(struct audio_port_v7* port) } /* Connect a patch between several source and sink ports */ status_t PatchPanel::createAudioPatch(const struct audio_patch* patch, status_t PatchPanel::createAudioPatch_l(const struct audio_patch* patch, audio_patch_handle_t *handle, bool endpointPatch) //unlocks AudioFlinger::mLock when calling IAfThreadBase::sendCreateAudioPatchConfigEvent Loading Loading @@ -144,7 +144,7 @@ status_t PatchPanel::createAudioPatch(const struct audio_patch* patch, // 1) if a software patch is present, release the playback and capture threads and // tracks created. This will also release the corresponding audio HAL patches if (removedPatch.isSoftware()) { removedPatch.clearConnections(this); removedPatch.clearConnections_l(this); } // 2) if the new patch and old patch source or sink are devices from different // hw modules, clear the audio HAL patches now because they will not be updated Loading @@ -169,7 +169,7 @@ status_t PatchPanel::createAudioPatch(const struct audio_patch* patch, // removedPatch.mHalHandle would be AUDIO_PATCH_HANDLE_NONE in this case. hwModule = oldPatch.sinks[0].ext.device.hw_module; } sp<DeviceHalInterface> hwDevice = findHwDeviceByModule(hwModule); sp<DeviceHalInterface> hwDevice = findHwDeviceByModule_l(hwModule); if (hwDevice != 0) { hwDevice->releaseAudioPatch(removedPatch.mHalHandle); } Loading @@ -185,7 +185,7 @@ status_t PatchPanel::createAudioPatch(const struct audio_patch* patch, switch (patch->sources[0].type) { case AUDIO_PORT_TYPE_DEVICE: { audio_module_handle_t srcModule = patch->sources[0].ext.device.hw_module; AudioHwDevice *audioHwDevice = findAudioHwDeviceByModule(srcModule); AudioHwDevice *audioHwDevice = findAudioHwDeviceByModule_l(srcModule); if (!audioHwDevice) { status = BAD_VALUE; goto exit; Loading Loading @@ -317,7 +317,7 @@ status_t PatchPanel::createAudioPatch(const struct audio_patch* patch, goto exit; } newPatch.mRecord.setThread(thread->asIAfRecordThread().get()); status = newPatch.createConnections(this); status = newPatch.createConnections_l(this); if (status != NO_ERROR) { goto exit; } Loading Loading @@ -438,11 +438,11 @@ exit: newPatch.mHalHandle = halHandle; mAfPatchPanelCallback->getPatchCommandThread()->createAudioPatch(*handle, newPatch); if (insertedModule != AUDIO_MODULE_HANDLE_NONE) { addSoftwarePatchToInsertedModules(insertedModule, *handle, &newPatch.mAudioPatch); addSoftwarePatchToInsertedModules_l(insertedModule, *handle, &newPatch.mAudioPatch); } mPatches.insert(std::make_pair(*handle, std::move(newPatch))); } else { newPatch.clearConnections(this); newPatch.clearConnections_l(this); } return status; } Loading @@ -453,10 +453,10 @@ PatchPanel::Patch::~Patch() mRecord.handle(), mPlayback.handle()); } status_t PatchPanel::Patch::createConnections(const sp<IAfPatchPanel>& panel) status_t PatchPanel::Patch::createConnections_l(const sp<IAfPatchPanel>& panel) { // create patch from source device to record thread input status_t status = panel->createAudioPatch( status_t status = panel->createAudioPatch_l( PatchBuilder().addSource(mAudioPatch.sources[0]). addSink(mRecord.thread(), { .source = AUDIO_SOURCE_MIC }).patch(), mRecord.handlePtr(), Loading @@ -468,7 +468,7 @@ status_t PatchPanel::Patch::createConnections(const sp<IAfPatchPanel>& panel) // create patch from playback thread output to sink device if (mAudioPatch.num_sinks != 0) { status = panel->createAudioPatch( status = panel->createAudioPatch_l( PatchBuilder().addSource(mPlayback.thread()).addSink(mAudioPatch.sinks[0]).patch(), mPlayback.handlePtr(), true /*endpointPatch*/); Loading Loading @@ -617,15 +617,15 @@ status_t PatchPanel::Patch::createConnections(const sp<IAfPatchPanel>& panel) return status; } void PatchPanel::Patch::clearConnections(const sp<IAfPatchPanel>& panel) void PatchPanel::Patch::clearConnections_l(const sp<IAfPatchPanel>& panel) { ALOGV("%s() mRecord.handle %d mPlayback.handle %d", __func__, mRecord.handle(), mPlayback.handle()); mRecord.stopTrack(); mPlayback.stopTrack(); mRecord.clearTrackPeer(); // mRecord stop is synchronous. Break PeerProxy sp<> cycle. mRecord.closeConnections(panel); mPlayback.closeConnections(panel); mRecord.closeConnections_l(panel); mPlayback.closeConnections_l(panel); } status_t PatchPanel::Patch::getLatencyMs(double* latencyMs) const Loading Loading @@ -715,7 +715,7 @@ String8 PatchPanel::Patch::dump(audio_patch_handle_t myHandle) const } /* Disconnect a patch */ status_t PatchPanel::releaseAudioPatch(audio_patch_handle_t handle) status_t PatchPanel::releaseAudioPatch_l(audio_patch_handle_t handle) //unlocks AudioFlinger::mLock when calling IAfThreadBase::sendReleaseAudioPatchConfigEvent //to avoid deadlocks if the thread loop needs to acquire AudioFlinger::mLock //before processing the release patch request. Loading @@ -734,7 +734,7 @@ status_t PatchPanel::releaseAudioPatch(audio_patch_handle_t handle) const struct audio_port_config &src = patch.sources[0]; switch (src.type) { case AUDIO_PORT_TYPE_DEVICE: { sp<DeviceHalInterface> hwDevice = findHwDeviceByModule(src.ext.device.hw_module); sp<DeviceHalInterface> hwDevice = findHwDeviceByModule_l(src.ext.device.hw_module); if (hwDevice == 0) { ALOGW("%s() bad src hw module %d", __func__, src.ext.device.hw_module); status = BAD_VALUE; Loading @@ -742,7 +742,7 @@ status_t PatchPanel::releaseAudioPatch(audio_patch_handle_t handle) } if (removedPatch.isSoftware()) { removedPatch.clearConnections(this); removedPatch.clearConnections_l(this); break; } Loading @@ -765,7 +765,7 @@ status_t PatchPanel::releaseAudioPatch(audio_patch_handle_t handle) } } break; case AUDIO_PORT_TYPE_MIX: { if (findHwDeviceByModule(src.ext.mix.hw_module) == 0) { if (findHwDeviceByModule_l(src.ext.mix.hw_module) == 0) { ALOGW("%s() bad src hw module %d", __func__, src.ext.mix.hw_module); status = BAD_VALUE; break; Loading Loading @@ -799,7 +799,7 @@ void PatchPanel::erasePatch(audio_patch_handle_t handle) { } /* List connected audio ports and they attributes */ status_t PatchPanel::listAudioPatches(unsigned int* /* num_patches */, status_t PatchPanel::listAudioPatches_l(unsigned int* /* num_patches */, struct audio_patch *patches __unused) { ALOGV(__func__); Loading Loading @@ -856,7 +856,7 @@ void PatchPanel::notifyStreamClosed(audio_io_handle_t stream) } } AudioHwDevice* PatchPanel::findAudioHwDeviceByModule(audio_module_handle_t module) AudioHwDevice* PatchPanel::findAudioHwDeviceByModule_l(audio_module_handle_t module) { if (module == AUDIO_MODULE_HANDLE_NONE) return nullptr; ssize_t index = mAfPatchPanelCallback->getAudioHwDevs_l().indexOfKey(module); Loading @@ -867,13 +867,13 @@ AudioHwDevice* PatchPanel::findAudioHwDeviceByModule(audio_module_handle_t modul return mAfPatchPanelCallback->getAudioHwDevs_l().valueAt(index); } sp<DeviceHalInterface> PatchPanel::findHwDeviceByModule(audio_module_handle_t module) sp<DeviceHalInterface> PatchPanel::findHwDeviceByModule_l(audio_module_handle_t module) { AudioHwDevice *audioHwDevice = findAudioHwDeviceByModule(module); AudioHwDevice *audioHwDevice = findAudioHwDeviceByModule_l(module); return audioHwDevice ? audioHwDevice->hwDevice() : nullptr; } void PatchPanel::addSoftwarePatchToInsertedModules( void PatchPanel::addSoftwarePatchToInsertedModules_l( audio_module_handle_t module, audio_patch_handle_t handle, const struct audio_patch *patch) { Loading
services/audioflinger/PatchPanel.h +26 −18 Original line number Diff line number Diff line Loading @@ -30,25 +30,29 @@ public: : mAfPatchPanelCallback(afPatchPanelCallback) {} /* List connected audio ports and their attributes */ status_t listAudioPorts(unsigned int *num_ports, struct audio_port* ports) final; status_t listAudioPorts_l(unsigned int *num_ports, struct audio_port* ports) final REQUIRES(audio_utils::AudioFlinger_Mutex); /* Get supported attributes for a given audio port */ status_t getAudioPort(struct audio_port_v7* port) final; status_t getAudioPort_l(struct audio_port_v7* port) final REQUIRES(audio_utils::AudioFlinger_Mutex); /* Create a patch between several source and sink ports */ status_t createAudioPatch(const struct audio_patch *patch, status_t createAudioPatch_l(const struct audio_patch *patch, audio_patch_handle_t *handle, bool endpointPatch = false) final; bool endpointPatch = false) final REQUIRES(audio_utils::AudioFlinger_Mutex); /* Release a patch */ status_t releaseAudioPatch(audio_patch_handle_t handle) final; status_t releaseAudioPatch_l(audio_patch_handle_t handle) final REQUIRES(audio_utils::AudioFlinger_Mutex); /* List connected audio devices and they attributes */ status_t listAudioPatches(unsigned int *num_patches, struct audio_patch* patches) final; status_t listAudioPatches_l(unsigned int *num_patches, struct audio_patch* patches) final REQUIRES(audio_utils::AudioFlinger_Mutex); // Retrieves all currently estrablished software patches for a stream // Retrieves all currently established software patches for a stream // opened on an intermediate module. status_t getDownstreamSoftwarePatches(audio_io_handle_t stream, std::vector<SoftwarePatch>* patches) const final; Loading @@ -60,20 +64,24 @@ public: void dump(int fd) const final; // Call with AudioFlinger mLock held const std::map<audio_patch_handle_t, Patch>& patches_l() const final { return mPatches; } const std::map<audio_patch_handle_t, Patch>& patches_l() const final REQUIRES(audio_utils::AudioFlinger_Mutex) { return mPatches; } // Must be called under AudioFlinger::mLock status_t getLatencyMs_l(audio_patch_handle_t patchHandle, double* latencyMs) const final; status_t getLatencyMs_l(audio_patch_handle_t patchHandle, double* latencyMs) const final REQUIRES(audio_utils::AudioFlinger_Mutex); void closeThreadInternal_l(const sp<IAfThreadBase>& thread) const final; void closeThreadInternal_l(const sp<IAfThreadBase>& thread) const final REQUIRES(audio_utils::AudioFlinger_Mutex); private: AudioHwDevice* findAudioHwDeviceByModule(audio_module_handle_t module); sp<DeviceHalInterface> findHwDeviceByModule(audio_module_handle_t module); void addSoftwarePatchToInsertedModules( AudioHwDevice* findAudioHwDeviceByModule_l(audio_module_handle_t module) REQUIRES(audio_utils::AudioFlinger_Mutex); sp<DeviceHalInterface> findHwDeviceByModule_l(audio_module_handle_t module) REQUIRES(audio_utils::AudioFlinger_Mutex); void addSoftwarePatchToInsertedModules_l( audio_module_handle_t module, audio_patch_handle_t handle, const struct audio_patch *patch); const struct audio_patch *patch) REQUIRES(audio_utils::AudioFlinger_Mutex); void removeSoftwarePatchFromInsertedModules(audio_patch_handle_t handle); void erasePatch(audio_patch_handle_t handle); Loading