Loading media/audioserver/main_audioserver.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -184,7 +184,7 @@ int main(int argc __unused, char **argv) // attempting to call audio flinger on a null pointer could make the process crash // and attract attentions. std::vector<AudioMMapPolicyInfo> policyInfos; status_t status = af->getMmapPolicyInfos( status_t status = sp<IAudioFlinger>::cast(af)->getMmapPolicyInfos( AudioMMapPolicyType::DEFAULT, &policyInfos); // Initialize aaudio service when querying mmap policy succeeds and // any of the policy supports MMAP. Loading services/audioflinger/AudioFlinger.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -528,7 +528,7 @@ status_t AudioFlinger::setSimulateDeviceConnections(bool enabled) { } // getDefaultVibratorInfo_l must be called with AudioFlinger lock held. std::optional<media::AudioVibratorInfo> AudioFlinger::getDefaultVibratorInfo_l() { std::optional<media::AudioVibratorInfo> AudioFlinger::getDefaultVibratorInfo_l() const { if (mAudioVibratorInfos.empty()) { return {}; } Loading Loading @@ -4662,7 +4662,7 @@ Exit: return status; } bool AudioFlinger::isNonOffloadableGlobalEffectEnabled_l() bool AudioFlinger::isNonOffloadableGlobalEffectEnabled_l() const NO_THREAD_SAFETY_ANALYSIS // thread lock for getEffectChain_l. { if (mGlobalEffectEnableTime != 0 && Loading services/audioflinger/AudioFlinger.h +66 −96 Original line number Diff line number Diff line Loading @@ -122,9 +122,6 @@ #include "Client.h" #include "ResamplerBufferProvider.h" // TODO(b/291319167) remove me when AudioFlinger class not directly used by subcomponents namespace android { class AudioFlinger; } // include AudioFlinger component interfaces #include "IAfPatchPanel.h" // this should be listed before other IAf* interfaces. #include "IAfEffect.h" Loading Loading @@ -167,24 +164,17 @@ class AudioFlinger , public IAfDeviceEffectManagerCallback , public IAfMelReporterCallback , public IAfPatchPanelCallback , public IAfThreadCallback { friend class sp<AudioFlinger>; // TODO(b/291319167) Create interface and remove friends. // TODO(b/291012167) replace the Thread friends with an interface. friend class DirectOutputThread; friend class MixerThread; friend class MmapPlaybackThread; friend class MmapThread; friend class PlaybackThread; friend class RecordThread; friend class ThreadBase; public: static void instantiate() ANDROID_API; static AttributionSourceState checkAttributionSourcePackage( const AttributionSourceState& attributionSource); private: // ---- begin IAudioFlinger interface status_t dump(int fd, const Vector<String16>& args) final; Loading Loading @@ -324,7 +314,7 @@ public: status_t getMmapPolicyInfos( media::audio::common::AudioMMapPolicyType policyType, std::vector<media::audio::common::AudioMMapPolicyInfo>* policyInfos) override; std::vector<media::audio::common::AudioMMapPolicyInfo>* policyInfos) final; int32_t getAAudioMixerBurstCount() const final; Loading Loading @@ -373,6 +363,7 @@ public: // ---- begin IAfDeviceEffectManagerCallback interface // also used by IAfThreadCallback bool isAudioPolicyReady() const final { return mAudioPolicyReady.load(); } // below also used by IAfMelReporterCallback, IAfPatchPanelCallback const sp<PatchCommandThread>& getPatchCommandThread() final { return mPatchCommandThread; } Loading @@ -385,6 +376,7 @@ public: // ---- begin IAfMelReporterCallback interface // below also used by IAfThreadCallback Mutex& mutex() const final { return mLock; } sp<IAfThreadBase> checkOutputThread_l(audio_io_handle_t ioHandle) const final REQUIRES(mLock); Loading Loading @@ -425,13 +417,62 @@ public: // ---- end of IAfPatchPanelCallback interface // ----- begin IAfThreadCallback interface bool isNonOffloadableGlobalEffectEnabled_l() const final; bool btNrecIsOff() const final { return mBtNrecIsOff.load(); } float masterVolume_l() const final; bool masterMute_l() const final; float getMasterBalance_l() const; // no range check, AudioFlinger::mLock held bool streamMute_l(audio_stream_type_t stream) const final { return mStreamTypes[stream].mute; } audio_mode_t getMode() const final { return mMode; } bool isLowRamDevice() const final { return mIsLowRamDevice; } std::optional<media::AudioVibratorInfo> getDefaultVibratorInfo_l() const final; const sp<IAfPatchPanel>& getPatchPanel() const final { return mPatchPanel; } const sp<MelReporter>& getMelReporter() const final { return mMelReporter; } const sp<EffectsFactoryHalInterface>& getEffectsFactoryHal() const final { return mEffectsFactoryHal; } sp<IAudioManager> getOrCreateAudioManager() final; // Called when the last effect handle on an effect instance is removed. If this // effect belongs to an effect chain in mOrphanEffectChains, the chain is updated // and removed from mOrphanEffectChains if it does not contain any effect. // Return true if the effect was found in mOrphanEffectChains, false otherwise. bool updateOrphanEffectChains(const sp<IAfEffectModule>& effect) final; status_t moveEffectChain_l(audio_session_t sessionId, IAfPlaybackThread* srcThread, IAfPlaybackThread* dstThread) final; // This is a helper that is called during incoming binder calls. // Requests media.log to start merging log buffers void requestLogMerge() final; sp<NBLog::Writer> newWriter_l(size_t size, const char *name) final; void unregisterWriter(const sp<NBLog::Writer>& writer) final; sp<audioflinger::SyncEvent> createSyncEvent(AudioSystem::sync_event_t type, audio_session_t triggerSession, audio_session_t listenerSession, const audioflinger::SyncEventCallback& callBack, const wp<IAfTrackBase>& cookie) final; void ioConfigChanged(audio_io_config_event_t event, const sp<AudioIoDescriptor>& ioDesc, pid_t pid = 0) final; void onNonOffloadableGlobalEffectEnable() final; void onSupportedLatencyModesChanged( audio_io_handle_t output, const std::vector<audio_latency_mode_t>& modes) final; // ---- end of IAfThreadCallback interface /* List available audio ports and their attributes */ status_t listAudioPorts(unsigned int* num_ports, struct audio_port* ports) const; sp<NBLog::Writer> newWriter_l(size_t size, const char *name); void unregisterWriter(const sp<NBLog::Writer>& writer); sp<EffectsFactoryHalInterface> getEffectsFactory(); public: status_t openMmapStream(MmapStreamInterface::stream_direction_t direction, const audio_attributes_t *attr, audio_config_base_t *config, Loading @@ -446,8 +487,6 @@ public: const sp<os::ExternalVibration>& externalVibration); static void onExternalVibrationStop(const sp<os::ExternalVibration>& externalVibration); std::optional<media::AudioVibratorInfo> getDefaultVibratorInfo_l(); private: // FIXME The 400 is temporarily too high until a leak of writers in media.log is fixed. static const size_t kLogMemorySize = 400 * 1024; Loading @@ -457,38 +496,6 @@ private: Vector< sp<NBLog::Writer> > mUnregisteredWriters; Mutex mUnregisteredWritersLock; public: // Life cycle of gAudioFlinger and AudioFlinger: // // AudioFlinger is created once and survives until audioserver crashes // irrespective of sp<> and wp<> as it is refcounted by ServiceManager and we // don't issue a ServiceManager::tryUnregisterService(). // // gAudioFlinger is an atomic pointer set on AudioFlinger::onFirstRef(). // After this is set, it is safe to obtain a wp<> or sp<> from it as the // underlying object does not go away. // // Note: For most inner classes, it is acceptable to hold a reference to the outer // AudioFlinger instance as creation requires AudioFlinger to exist in the first place. // // An atomic here ensures underlying writes have completed before setting // the pointer. Access by memory_order_seq_cst. // static inline std::atomic<AudioFlinger *> gAudioFlinger = nullptr; sp<audioflinger::SyncEvent> createSyncEvent(AudioSystem::sync_event_t type, audio_session_t triggerSession, audio_session_t listenerSession, const audioflinger::SyncEventCallback& callBack, const wp<IAfTrackBase>& cookie); bool btNrecIsOff() const { return mBtNrecIsOff.load(); } private: audio_mode_t getMode() const { return mMode; } AudioFlinger() ANDROID_API; ~AudioFlinger() override; Loading @@ -507,6 +514,10 @@ private: // FCC_2 <= channels <= AudioMixer::MAX_NUM_CHANNELS. static const bool kEnableExtendedChannels = true; public: // Remove this when Oboeservice is updated to obtain handle directly. static inline std::atomic<AudioFlinger*> gAudioFlinger = nullptr; // Returns true if channel mask is permitted for the PCM sink in the MixerThread static inline bool isValidPcmSinkChannelMask(audio_channel_mask_t channelMask) { switch (audio_channel_mask_get_representation(channelMask)) { Loading Loading @@ -565,7 +576,7 @@ private: // Internal dump utilities. static const int kDumpLockTimeoutNs = 1 * NANOS_PER_SECOND; public: // TODO(b/291319167) extract to afutils static bool dumpTryLock(Mutex& mutex); private: Loading Loading @@ -631,10 +642,6 @@ private: const sp<MediaLogNotifier> mMediaLogNotifier; // This is a helper that is called during incoming binder calls. // Requests media.log to start merging log buffers void requestLogMerge(); // Find io handle by session id. // Preference is given to an io handle with a matching effect chain to session id. // If none found, AUDIO_IO_HANDLE_NONE is returned. Loading Loading @@ -665,15 +672,6 @@ private: void closeOutputFinish(const sp<IAfPlaybackThread>& thread); void closeInputFinish(const sp<IAfRecordThread>& thread); // no range check, AudioFlinger::mLock held bool streamMute_l(audio_stream_type_t stream) const { return mStreamTypes[stream].mute; } void ioConfigChanged(audio_io_config_event_t event, const sp<AudioIoDescriptor>& ioDesc, pid_t pid = 0); void onSupportedLatencyModesChanged( audio_io_handle_t output, const std::vector<audio_latency_mode_t>& modes); // Allocate an audio_unique_id_t. // Specific types are audio_io_handle_t, audio_session_t, effect ID (int), // audio_module_handle_t, and audio_patch_handle_t. Loading @@ -685,12 +683,9 @@ 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, IAfPatchPanelCallback // used by IAfDeviceEffectManagerCallback, IAfPatchPanelCallback, IAfThreadCallback 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 DeviceTypeSet primaryOutputDevice_l() const; Loading @@ -706,11 +701,6 @@ private: IAfPlaybackThread* thread, const std::vector<audio_io_handle_t>& secondaryOutputs) const; public: // TODO(b/291319167) cluster together bool isNonOffloadableGlobalEffectEnabled_l(); private: void onNonOffloadableGlobalEffectEnable(); bool isSessionAcquired_l(audio_session_t audioSession); // Store an effect chain to mOrphanEffectChains keyed vector. Loading @@ -724,14 +714,7 @@ private: // Get an effect chain for the specified session in mOrphanEffectChains and remove // it if found. Returns 0 if not found (this is the most common case). sp<IAfEffectChain> getOrphanEffectChain_l(audio_session_t session); // Called when the last effect handle on an effect instance is removed. If this // effect belongs to an effect chain in mOrphanEffectChains, the chain is updated // and removed from mOrphanEffectChains if it does not contain any effect. // Return true if the effect was found in mOrphanEffectChains, false otherwise. public: // TODO(b/291319167) suggest better grouping bool updateOrphanEffectChains(const sp<IAfEffectModule>& effect); private: std::vector< sp<IAfEffectModule> > purgeStaleEffects_l(); void broadcastParametersToRecordThreads_l(const String8& keyValuePairs); Loading @@ -749,14 +732,11 @@ private: int mCnt; }; public: // TODO(b/291319167) access by getter, mutable Mutex mLock; // protects mClients and mNotificationClients. // must be locked after mLock and ThreadBase::mLock if both must be locked // avoids acquiring AudioFlinger::mLock from inside thread loop. private: mutable Mutex mClientLock; // protected by mClientLock Loading Loading @@ -828,9 +808,6 @@ private: // protected by mLock Vector<AudioSessionRef*> mAudioSessionRefs; float masterVolume_l() const; float getMasterBalance_l() const; bool masterMute_l() const; AudioHwDevice* loadHwModule_l(const char *name); // sync events awaiting for a session to be created. Loading @@ -847,7 +824,6 @@ private: // Audio data transfer is directly handled by the client creating the MMAP stream DefaultKeyedVector<audio_io_handle_t, sp<IAfMmapThread>> mMmapThreads; private: sp<Client> registerPid(pid_t pid); // always returns non-0 // for use from destructor Loading @@ -862,15 +838,10 @@ private: size_t rejectedKVPSize, const String8& rejectedKVPs, uid_t callingUid); public: sp<IAudioManager> getOrCreateAudioManager(); // These methods read variables atomically without mLock, // though the variables are updated with mLock. bool isLowRamDevice() const { return mIsLowRamDevice; } size_t getClientSharedHeapSize() const; private: std::atomic<bool> mIsLowRamDevice; bool mIsDeviceTypeKnown; int64_t mTotalMemory; Loading @@ -881,10 +852,7 @@ private: /* const */ sp<IAfPatchPanel> mPatchPanel; public: // TODO(b/291319167) access by getter. sp<EffectsFactoryHalInterface> mEffectsFactoryHal; private: const sp<PatchCommandThread> mPatchCommandThread; /* const */ sp<DeviceEffectManager> mDeviceEffectManager; // set onFirstRef Loading @@ -903,8 +871,10 @@ private: static inline constexpr const char *mMetricsId = AMEDIAMETRICS_KEY_AUDIO_FLINGER; public: // Keep in sync with java definition in media/java/android/media/AudioRecord.java static constexpr int32_t kMaxSharedAudioHistoryMs = 5000; private: std::map<media::audio::common::AudioMMapPolicyType, std::vector<media::audio::common::AudioMMapPolicyInfo>> mPolicyInfos; Loading services/audioflinger/Effects.cpp +8 −16 Original line number Diff line number Diff line Loading @@ -2116,30 +2116,22 @@ NO_THREAD_SAFETY_ANALYSIS // conditional try lock /* static */ sp<IAfEffectChain> IAfEffectChain::create( const wp<IAfThreadBase>& wThread, const sp<IAfThreadBase>& thread, audio_session_t sessionId) { return sp<EffectChain>::make(wThread, sessionId); return sp<EffectChain>::make(thread, sessionId); } EffectChain::EffectChain(const wp<IAfThreadBase>& thread, EffectChain::EffectChain(const sp<IAfThreadBase>& thread, audio_session_t sessionId) : mSessionId(sessionId), mActiveTrackCnt(0), mTrackCnt(0), mTailBufferCount(0), mVolumeCtrlIdx(-1), mLeftVolume(UINT_MAX), mRightVolume(UINT_MAX), mNewLeftVolume(UINT_MAX), mNewRightVolume(UINT_MAX), mEffectCallback(new EffectCallback(wp<EffectChain>(this), thread)) { const sp<IAfThreadBase> p = thread.promote(); if (p == nullptr) { return; } mStrategy = p->getStrategyForStream(AUDIO_STREAM_MUSIC); mMaxTailBuffers = ((kProcessTailDurationMs * p->sampleRate()) / 1000) / p->frameCount(); } EffectChain::~EffectChain() { mStrategy = thread->getStrategyForStream(AUDIO_STREAM_MUSIC); mMaxTailBuffers = ((kProcessTailDurationMs * thread->sampleRate()) / 1000) / thread->frameCount(); } // getEffectFromDesc_l() must be called with IAfThreadBase::mutex() held Loading Loading @@ -2988,12 +2980,12 @@ status_t EffectChain::EffectCallback::createEffectHal( bool EffectChain::EffectCallback::updateOrphanEffectChains( const sp<IAfEffectBase>& effect) { // in EffectChain context, an EffectBase is always from an EffectModule so static cast is safe return mAudioFlinger.updateOrphanEffectChains(effect->asEffectModule()); return mAfThreadCallback->updateOrphanEffectChains(effect->asEffectModule()); } status_t EffectChain::EffectCallback::allocateHalBuffer( size_t size, sp<EffectBufferHalInterface>* buffer) { return mAudioFlinger.mEffectsFactoryHal->allocateBuffer(size, buffer); return mAfThreadCallback->getEffectsFactoryHal()->allocateBuffer(size, buffer); } status_t EffectChain::EffectCallback::addEffectToHal( Loading services/audioflinger/Effects.h +8 −13 Original line number Diff line number Diff line Loading @@ -382,8 +382,7 @@ private: // it also provide it's own input buffer used by the track as accumulation buffer. class EffectChain : public IAfEffectChain { public: EffectChain(const wp<IAfThreadBase>& wThread, audio_session_t sessionId); ~EffectChain() override; EffectChain(const sp<IAfThreadBase>& thread, audio_session_t sessionId); void process_l() final; Loading Loading @@ -516,16 +515,11 @@ private: // Note: ctors taking a weak pointer to their owner must not promote it // during construction (but may keep a reference for later promotion). EffectCallback(const wp<EffectChain>& owner, const wp<IAfThreadBase>& thread) const sp<IAfThreadBase>& thread) // we take a sp<> but store a wp<>. : mChain(owner) , mThread(thread) , mAudioFlinger(*AudioFlinger::gAudioFlinger) { const sp<IAfThreadBase> base = thread.promote(); if (base != nullptr) { mThreadType = base->type(); } else { mThreadType = IAfThreadBase::MIXER; // assure a consistent value. } , mThread(thread) { mThreadType = thread->type(); mAfThreadCallback = thread->afThreadCallback(); } status_t createEffectHal(const effect_uuid_t *pEffectUuid, Loading Loading @@ -566,7 +560,7 @@ private: wp<IAfEffectChain> chain() const final { return mChain; } bool isAudioPolicyReady() const final { return mAudioFlinger.isAudioPolicyReady(); return mAfThreadCallback->isAudioPolicyReady(); } wp<IAfThreadBase> thread() const { return mThread.load(); } Loading @@ -574,12 +568,13 @@ private: void setThread(const sp<IAfThreadBase>& thread) { mThread = thread; mThreadType = thread->type(); mAfThreadCallback = thread->afThreadCallback(); } private: const wp<IAfEffectChain> mChain; mediautils::atomic_wp<IAfThreadBase> mThread; AudioFlinger &mAudioFlinger; // implementation detail: outer instance always exists. sp<IAfThreadCallback> mAfThreadCallback; IAfThreadBase::type_t mThreadType; }; Loading Loading
media/audioserver/main_audioserver.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -184,7 +184,7 @@ int main(int argc __unused, char **argv) // attempting to call audio flinger on a null pointer could make the process crash // and attract attentions. std::vector<AudioMMapPolicyInfo> policyInfos; status_t status = af->getMmapPolicyInfos( status_t status = sp<IAudioFlinger>::cast(af)->getMmapPolicyInfos( AudioMMapPolicyType::DEFAULT, &policyInfos); // Initialize aaudio service when querying mmap policy succeeds and // any of the policy supports MMAP. Loading
services/audioflinger/AudioFlinger.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -528,7 +528,7 @@ status_t AudioFlinger::setSimulateDeviceConnections(bool enabled) { } // getDefaultVibratorInfo_l must be called with AudioFlinger lock held. std::optional<media::AudioVibratorInfo> AudioFlinger::getDefaultVibratorInfo_l() { std::optional<media::AudioVibratorInfo> AudioFlinger::getDefaultVibratorInfo_l() const { if (mAudioVibratorInfos.empty()) { return {}; } Loading Loading @@ -4662,7 +4662,7 @@ Exit: return status; } bool AudioFlinger::isNonOffloadableGlobalEffectEnabled_l() bool AudioFlinger::isNonOffloadableGlobalEffectEnabled_l() const NO_THREAD_SAFETY_ANALYSIS // thread lock for getEffectChain_l. { if (mGlobalEffectEnableTime != 0 && Loading
services/audioflinger/AudioFlinger.h +66 −96 Original line number Diff line number Diff line Loading @@ -122,9 +122,6 @@ #include "Client.h" #include "ResamplerBufferProvider.h" // TODO(b/291319167) remove me when AudioFlinger class not directly used by subcomponents namespace android { class AudioFlinger; } // include AudioFlinger component interfaces #include "IAfPatchPanel.h" // this should be listed before other IAf* interfaces. #include "IAfEffect.h" Loading Loading @@ -167,24 +164,17 @@ class AudioFlinger , public IAfDeviceEffectManagerCallback , public IAfMelReporterCallback , public IAfPatchPanelCallback , public IAfThreadCallback { friend class sp<AudioFlinger>; // TODO(b/291319167) Create interface and remove friends. // TODO(b/291012167) replace the Thread friends with an interface. friend class DirectOutputThread; friend class MixerThread; friend class MmapPlaybackThread; friend class MmapThread; friend class PlaybackThread; friend class RecordThread; friend class ThreadBase; public: static void instantiate() ANDROID_API; static AttributionSourceState checkAttributionSourcePackage( const AttributionSourceState& attributionSource); private: // ---- begin IAudioFlinger interface status_t dump(int fd, const Vector<String16>& args) final; Loading Loading @@ -324,7 +314,7 @@ public: status_t getMmapPolicyInfos( media::audio::common::AudioMMapPolicyType policyType, std::vector<media::audio::common::AudioMMapPolicyInfo>* policyInfos) override; std::vector<media::audio::common::AudioMMapPolicyInfo>* policyInfos) final; int32_t getAAudioMixerBurstCount() const final; Loading Loading @@ -373,6 +363,7 @@ public: // ---- begin IAfDeviceEffectManagerCallback interface // also used by IAfThreadCallback bool isAudioPolicyReady() const final { return mAudioPolicyReady.load(); } // below also used by IAfMelReporterCallback, IAfPatchPanelCallback const sp<PatchCommandThread>& getPatchCommandThread() final { return mPatchCommandThread; } Loading @@ -385,6 +376,7 @@ public: // ---- begin IAfMelReporterCallback interface // below also used by IAfThreadCallback Mutex& mutex() const final { return mLock; } sp<IAfThreadBase> checkOutputThread_l(audio_io_handle_t ioHandle) const final REQUIRES(mLock); Loading Loading @@ -425,13 +417,62 @@ public: // ---- end of IAfPatchPanelCallback interface // ----- begin IAfThreadCallback interface bool isNonOffloadableGlobalEffectEnabled_l() const final; bool btNrecIsOff() const final { return mBtNrecIsOff.load(); } float masterVolume_l() const final; bool masterMute_l() const final; float getMasterBalance_l() const; // no range check, AudioFlinger::mLock held bool streamMute_l(audio_stream_type_t stream) const final { return mStreamTypes[stream].mute; } audio_mode_t getMode() const final { return mMode; } bool isLowRamDevice() const final { return mIsLowRamDevice; } std::optional<media::AudioVibratorInfo> getDefaultVibratorInfo_l() const final; const sp<IAfPatchPanel>& getPatchPanel() const final { return mPatchPanel; } const sp<MelReporter>& getMelReporter() const final { return mMelReporter; } const sp<EffectsFactoryHalInterface>& getEffectsFactoryHal() const final { return mEffectsFactoryHal; } sp<IAudioManager> getOrCreateAudioManager() final; // Called when the last effect handle on an effect instance is removed. If this // effect belongs to an effect chain in mOrphanEffectChains, the chain is updated // and removed from mOrphanEffectChains if it does not contain any effect. // Return true if the effect was found in mOrphanEffectChains, false otherwise. bool updateOrphanEffectChains(const sp<IAfEffectModule>& effect) final; status_t moveEffectChain_l(audio_session_t sessionId, IAfPlaybackThread* srcThread, IAfPlaybackThread* dstThread) final; // This is a helper that is called during incoming binder calls. // Requests media.log to start merging log buffers void requestLogMerge() final; sp<NBLog::Writer> newWriter_l(size_t size, const char *name) final; void unregisterWriter(const sp<NBLog::Writer>& writer) final; sp<audioflinger::SyncEvent> createSyncEvent(AudioSystem::sync_event_t type, audio_session_t triggerSession, audio_session_t listenerSession, const audioflinger::SyncEventCallback& callBack, const wp<IAfTrackBase>& cookie) final; void ioConfigChanged(audio_io_config_event_t event, const sp<AudioIoDescriptor>& ioDesc, pid_t pid = 0) final; void onNonOffloadableGlobalEffectEnable() final; void onSupportedLatencyModesChanged( audio_io_handle_t output, const std::vector<audio_latency_mode_t>& modes) final; // ---- end of IAfThreadCallback interface /* List available audio ports and their attributes */ status_t listAudioPorts(unsigned int* num_ports, struct audio_port* ports) const; sp<NBLog::Writer> newWriter_l(size_t size, const char *name); void unregisterWriter(const sp<NBLog::Writer>& writer); sp<EffectsFactoryHalInterface> getEffectsFactory(); public: status_t openMmapStream(MmapStreamInterface::stream_direction_t direction, const audio_attributes_t *attr, audio_config_base_t *config, Loading @@ -446,8 +487,6 @@ public: const sp<os::ExternalVibration>& externalVibration); static void onExternalVibrationStop(const sp<os::ExternalVibration>& externalVibration); std::optional<media::AudioVibratorInfo> getDefaultVibratorInfo_l(); private: // FIXME The 400 is temporarily too high until a leak of writers in media.log is fixed. static const size_t kLogMemorySize = 400 * 1024; Loading @@ -457,38 +496,6 @@ private: Vector< sp<NBLog::Writer> > mUnregisteredWriters; Mutex mUnregisteredWritersLock; public: // Life cycle of gAudioFlinger and AudioFlinger: // // AudioFlinger is created once and survives until audioserver crashes // irrespective of sp<> and wp<> as it is refcounted by ServiceManager and we // don't issue a ServiceManager::tryUnregisterService(). // // gAudioFlinger is an atomic pointer set on AudioFlinger::onFirstRef(). // After this is set, it is safe to obtain a wp<> or sp<> from it as the // underlying object does not go away. // // Note: For most inner classes, it is acceptable to hold a reference to the outer // AudioFlinger instance as creation requires AudioFlinger to exist in the first place. // // An atomic here ensures underlying writes have completed before setting // the pointer. Access by memory_order_seq_cst. // static inline std::atomic<AudioFlinger *> gAudioFlinger = nullptr; sp<audioflinger::SyncEvent> createSyncEvent(AudioSystem::sync_event_t type, audio_session_t triggerSession, audio_session_t listenerSession, const audioflinger::SyncEventCallback& callBack, const wp<IAfTrackBase>& cookie); bool btNrecIsOff() const { return mBtNrecIsOff.load(); } private: audio_mode_t getMode() const { return mMode; } AudioFlinger() ANDROID_API; ~AudioFlinger() override; Loading @@ -507,6 +514,10 @@ private: // FCC_2 <= channels <= AudioMixer::MAX_NUM_CHANNELS. static const bool kEnableExtendedChannels = true; public: // Remove this when Oboeservice is updated to obtain handle directly. static inline std::atomic<AudioFlinger*> gAudioFlinger = nullptr; // Returns true if channel mask is permitted for the PCM sink in the MixerThread static inline bool isValidPcmSinkChannelMask(audio_channel_mask_t channelMask) { switch (audio_channel_mask_get_representation(channelMask)) { Loading Loading @@ -565,7 +576,7 @@ private: // Internal dump utilities. static const int kDumpLockTimeoutNs = 1 * NANOS_PER_SECOND; public: // TODO(b/291319167) extract to afutils static bool dumpTryLock(Mutex& mutex); private: Loading Loading @@ -631,10 +642,6 @@ private: const sp<MediaLogNotifier> mMediaLogNotifier; // This is a helper that is called during incoming binder calls. // Requests media.log to start merging log buffers void requestLogMerge(); // Find io handle by session id. // Preference is given to an io handle with a matching effect chain to session id. // If none found, AUDIO_IO_HANDLE_NONE is returned. Loading Loading @@ -665,15 +672,6 @@ private: void closeOutputFinish(const sp<IAfPlaybackThread>& thread); void closeInputFinish(const sp<IAfRecordThread>& thread); // no range check, AudioFlinger::mLock held bool streamMute_l(audio_stream_type_t stream) const { return mStreamTypes[stream].mute; } void ioConfigChanged(audio_io_config_event_t event, const sp<AudioIoDescriptor>& ioDesc, pid_t pid = 0); void onSupportedLatencyModesChanged( audio_io_handle_t output, const std::vector<audio_latency_mode_t>& modes); // Allocate an audio_unique_id_t. // Specific types are audio_io_handle_t, audio_session_t, effect ID (int), // audio_module_handle_t, and audio_patch_handle_t. Loading @@ -685,12 +683,9 @@ 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, IAfPatchPanelCallback // used by IAfDeviceEffectManagerCallback, IAfPatchPanelCallback, IAfThreadCallback 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 DeviceTypeSet primaryOutputDevice_l() const; Loading @@ -706,11 +701,6 @@ private: IAfPlaybackThread* thread, const std::vector<audio_io_handle_t>& secondaryOutputs) const; public: // TODO(b/291319167) cluster together bool isNonOffloadableGlobalEffectEnabled_l(); private: void onNonOffloadableGlobalEffectEnable(); bool isSessionAcquired_l(audio_session_t audioSession); // Store an effect chain to mOrphanEffectChains keyed vector. Loading @@ -724,14 +714,7 @@ private: // Get an effect chain for the specified session in mOrphanEffectChains and remove // it if found. Returns 0 if not found (this is the most common case). sp<IAfEffectChain> getOrphanEffectChain_l(audio_session_t session); // Called when the last effect handle on an effect instance is removed. If this // effect belongs to an effect chain in mOrphanEffectChains, the chain is updated // and removed from mOrphanEffectChains if it does not contain any effect. // Return true if the effect was found in mOrphanEffectChains, false otherwise. public: // TODO(b/291319167) suggest better grouping bool updateOrphanEffectChains(const sp<IAfEffectModule>& effect); private: std::vector< sp<IAfEffectModule> > purgeStaleEffects_l(); void broadcastParametersToRecordThreads_l(const String8& keyValuePairs); Loading @@ -749,14 +732,11 @@ private: int mCnt; }; public: // TODO(b/291319167) access by getter, mutable Mutex mLock; // protects mClients and mNotificationClients. // must be locked after mLock and ThreadBase::mLock if both must be locked // avoids acquiring AudioFlinger::mLock from inside thread loop. private: mutable Mutex mClientLock; // protected by mClientLock Loading Loading @@ -828,9 +808,6 @@ private: // protected by mLock Vector<AudioSessionRef*> mAudioSessionRefs; float masterVolume_l() const; float getMasterBalance_l() const; bool masterMute_l() const; AudioHwDevice* loadHwModule_l(const char *name); // sync events awaiting for a session to be created. Loading @@ -847,7 +824,6 @@ private: // Audio data transfer is directly handled by the client creating the MMAP stream DefaultKeyedVector<audio_io_handle_t, sp<IAfMmapThread>> mMmapThreads; private: sp<Client> registerPid(pid_t pid); // always returns non-0 // for use from destructor Loading @@ -862,15 +838,10 @@ private: size_t rejectedKVPSize, const String8& rejectedKVPs, uid_t callingUid); public: sp<IAudioManager> getOrCreateAudioManager(); // These methods read variables atomically without mLock, // though the variables are updated with mLock. bool isLowRamDevice() const { return mIsLowRamDevice; } size_t getClientSharedHeapSize() const; private: std::atomic<bool> mIsLowRamDevice; bool mIsDeviceTypeKnown; int64_t mTotalMemory; Loading @@ -881,10 +852,7 @@ private: /* const */ sp<IAfPatchPanel> mPatchPanel; public: // TODO(b/291319167) access by getter. sp<EffectsFactoryHalInterface> mEffectsFactoryHal; private: const sp<PatchCommandThread> mPatchCommandThread; /* const */ sp<DeviceEffectManager> mDeviceEffectManager; // set onFirstRef Loading @@ -903,8 +871,10 @@ private: static inline constexpr const char *mMetricsId = AMEDIAMETRICS_KEY_AUDIO_FLINGER; public: // Keep in sync with java definition in media/java/android/media/AudioRecord.java static constexpr int32_t kMaxSharedAudioHistoryMs = 5000; private: std::map<media::audio::common::AudioMMapPolicyType, std::vector<media::audio::common::AudioMMapPolicyInfo>> mPolicyInfos; Loading
services/audioflinger/Effects.cpp +8 −16 Original line number Diff line number Diff line Loading @@ -2116,30 +2116,22 @@ NO_THREAD_SAFETY_ANALYSIS // conditional try lock /* static */ sp<IAfEffectChain> IAfEffectChain::create( const wp<IAfThreadBase>& wThread, const sp<IAfThreadBase>& thread, audio_session_t sessionId) { return sp<EffectChain>::make(wThread, sessionId); return sp<EffectChain>::make(thread, sessionId); } EffectChain::EffectChain(const wp<IAfThreadBase>& thread, EffectChain::EffectChain(const sp<IAfThreadBase>& thread, audio_session_t sessionId) : mSessionId(sessionId), mActiveTrackCnt(0), mTrackCnt(0), mTailBufferCount(0), mVolumeCtrlIdx(-1), mLeftVolume(UINT_MAX), mRightVolume(UINT_MAX), mNewLeftVolume(UINT_MAX), mNewRightVolume(UINT_MAX), mEffectCallback(new EffectCallback(wp<EffectChain>(this), thread)) { const sp<IAfThreadBase> p = thread.promote(); if (p == nullptr) { return; } mStrategy = p->getStrategyForStream(AUDIO_STREAM_MUSIC); mMaxTailBuffers = ((kProcessTailDurationMs * p->sampleRate()) / 1000) / p->frameCount(); } EffectChain::~EffectChain() { mStrategy = thread->getStrategyForStream(AUDIO_STREAM_MUSIC); mMaxTailBuffers = ((kProcessTailDurationMs * thread->sampleRate()) / 1000) / thread->frameCount(); } // getEffectFromDesc_l() must be called with IAfThreadBase::mutex() held Loading Loading @@ -2988,12 +2980,12 @@ status_t EffectChain::EffectCallback::createEffectHal( bool EffectChain::EffectCallback::updateOrphanEffectChains( const sp<IAfEffectBase>& effect) { // in EffectChain context, an EffectBase is always from an EffectModule so static cast is safe return mAudioFlinger.updateOrphanEffectChains(effect->asEffectModule()); return mAfThreadCallback->updateOrphanEffectChains(effect->asEffectModule()); } status_t EffectChain::EffectCallback::allocateHalBuffer( size_t size, sp<EffectBufferHalInterface>* buffer) { return mAudioFlinger.mEffectsFactoryHal->allocateBuffer(size, buffer); return mAfThreadCallback->getEffectsFactoryHal()->allocateBuffer(size, buffer); } status_t EffectChain::EffectCallback::addEffectToHal( Loading
services/audioflinger/Effects.h +8 −13 Original line number Diff line number Diff line Loading @@ -382,8 +382,7 @@ private: // it also provide it's own input buffer used by the track as accumulation buffer. class EffectChain : public IAfEffectChain { public: EffectChain(const wp<IAfThreadBase>& wThread, audio_session_t sessionId); ~EffectChain() override; EffectChain(const sp<IAfThreadBase>& thread, audio_session_t sessionId); void process_l() final; Loading Loading @@ -516,16 +515,11 @@ private: // Note: ctors taking a weak pointer to their owner must not promote it // during construction (but may keep a reference for later promotion). EffectCallback(const wp<EffectChain>& owner, const wp<IAfThreadBase>& thread) const sp<IAfThreadBase>& thread) // we take a sp<> but store a wp<>. : mChain(owner) , mThread(thread) , mAudioFlinger(*AudioFlinger::gAudioFlinger) { const sp<IAfThreadBase> base = thread.promote(); if (base != nullptr) { mThreadType = base->type(); } else { mThreadType = IAfThreadBase::MIXER; // assure a consistent value. } , mThread(thread) { mThreadType = thread->type(); mAfThreadCallback = thread->afThreadCallback(); } status_t createEffectHal(const effect_uuid_t *pEffectUuid, Loading Loading @@ -566,7 +560,7 @@ private: wp<IAfEffectChain> chain() const final { return mChain; } bool isAudioPolicyReady() const final { return mAudioFlinger.isAudioPolicyReady(); return mAfThreadCallback->isAudioPolicyReady(); } wp<IAfThreadBase> thread() const { return mThread.load(); } Loading @@ -574,12 +568,13 @@ private: void setThread(const sp<IAfThreadBase>& thread) { mThread = thread; mThreadType = thread->type(); mAfThreadCallback = thread->afThreadCallback(); } private: const wp<IAfEffectChain> mChain; mediautils::atomic_wp<IAfThreadBase> mThread; AudioFlinger &mAudioFlinger; // implementation detail: outer instance always exists. sp<IAfThreadCallback> mAfThreadCallback; IAfThreadBase::type_t mThreadType; }; Loading