Merge "AudioFlinger: Update MmapThread annotations" into main
diff --git a/services/audioflinger/IAfThread.h b/services/audioflinger/IAfThread.h
index a511acb..5a7429d 100644
--- a/services/audioflinger/IAfThread.h
+++ b/services/audioflinger/IAfThread.h
@@ -603,8 +603,8 @@
EXCLUDES_ThreadBase_Mutex = 0;
virtual bool hasFastCapture() const = 0;
- virtual void checkBtNrec() = 0;
- virtual uint32_t getInputFramesLost() const = 0;
+ virtual void checkBtNrec() EXCLUDES_ThreadBase_Mutex = 0;
+ virtual uint32_t getInputFramesLost() const EXCLUDES_ThreadBase_Mutex = 0;
virtual status_t shareAudioHistory(
const std::string& sharedAudioPackageName,
@@ -629,20 +629,24 @@
audio_session_t sessionId,
const sp<MmapStreamCallback>& callback,
audio_port_handle_t deviceId,
- audio_port_handle_t portId) = 0;
+ audio_port_handle_t portId) EXCLUDES_ThreadBase_Mutex = 0;
virtual void disconnect() EXCLUDES_ThreadBase_Mutex = 0;
// MmapStreamInterface handling (see adapter)
virtual status_t createMmapBuffer(
- int32_t minSizeFrames, struct audio_mmap_buffer_info* info) = 0;
- virtual status_t getMmapPosition(struct audio_mmap_position* position) const = 0;
+ int32_t minSizeFrames, struct audio_mmap_buffer_info* info)
+ EXCLUDES_ThreadBase_Mutex = 0;
+ virtual status_t getMmapPosition(struct audio_mmap_position* position) const
+ EXCLUDES_ThreadBase_Mutex = 0;
virtual status_t start(
const AudioClient& client, const audio_attributes_t* attr,
- audio_port_handle_t* handle) = 0;
- virtual status_t stop(audio_port_handle_t handle) = 0;
- virtual status_t standby() = 0;
- virtual status_t getExternalPosition(uint64_t* position, int64_t* timeNanos) const = 0;
- virtual status_t reportData(const void* buffer, size_t frameCount) = 0;
+ audio_port_handle_t* handle) EXCLUDES_ThreadBase_Mutex = 0;
+ virtual status_t stop(audio_port_handle_t handle) EXCLUDES_ThreadBase_Mutex = 0;
+ virtual status_t standby() EXCLUDES_ThreadBase_Mutex = 0;
+ virtual status_t getExternalPosition(uint64_t* position, int64_t* timeNanos) const
+ EXCLUDES_ThreadBase_Mutex = 0;
+ virtual status_t reportData(const void* buffer, size_t frameCount)
+ EXCLUDES_ThreadBase_Mutex = 0;
// TODO(b/291317898) move to IAfThreadBase?
virtual void invalidateTracks(std::set<audio_port_handle_t>& portIds)
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index f46ad16..a928ae2 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -10028,20 +10028,22 @@
void MmapThread::disconnect()
{
ActiveTracks<IAfMmapTrack> activeTracks;
+ audio_port_handle_t localPortId;
{
audio_utils::lock_guard _l(mutex());
for (const sp<IAfMmapTrack>& t : mActiveTracks) {
activeTracks.add(t);
}
+ localPortId = mPortId;
}
for (const sp<IAfMmapTrack>& t : activeTracks) {
stop(t->portId());
}
// This will decrement references and may cause the destruction of this thread.
if (isOutput()) {
- AudioSystem::releaseOutput(mPortId);
+ AudioSystem::releaseOutput(localPortId);
} else {
- AudioSystem::releaseInput(mPortId);
+ AudioSystem::releaseInput(localPortId);
}
}
@@ -10063,6 +10065,7 @@
status_t MmapThread::createMmapBuffer(int32_t minSizeFrames,
struct audio_mmap_buffer_info *info)
{
+ audio_utils::lock_guard l(mutex());
if (mHalStream == 0) {
return NO_INIT;
}
@@ -10072,6 +10075,7 @@
status_t MmapThread::getMmapPosition(struct audio_mmap_position* position) const
{
+ audio_utils::lock_guard l(mutex());
if (mHalStream == 0) {
return NO_INIT;
}
@@ -10099,6 +10103,7 @@
const audio_attributes_t *attr,
audio_port_handle_t *handle)
{
+ audio_utils::lock_guard l(mutex());
ALOGV("%s clientUid %d mStandby %d mPortId %d *handle %d", __FUNCTION__,
client.attributionSource.uid, mStandby, mPortId, *handle);
if (mHalStream == 0) {
@@ -10109,7 +10114,7 @@
// For the first track, reuse portId and session allocated when the stream was opened.
if (*handle == mPortId) {
- acquireWakeLock();
+ acquireWakeLock_l();
return NO_ERROR;
}
@@ -10119,20 +10124,23 @@
const AttributionSourceState adjAttributionSource = afutils::checkAttributionSourcePackage(
client.attributionSource);
+ const auto localSessionId = mSessionId;
+ auto localAttr = mAttr;
if (isOutput()) {
audio_config_t config = AUDIO_CONFIG_INITIALIZER;
config.sample_rate = mSampleRate;
config.channel_mask = mChannelMask;
config.format = mFormat;
- audio_stream_type_t stream = streamType();
+ audio_stream_type_t stream = streamType_l();
audio_output_flags_t flags =
(audio_output_flags_t)(AUDIO_OUTPUT_FLAG_MMAP_NOIRQ | AUDIO_OUTPUT_FLAG_DIRECT);
audio_port_handle_t deviceId = mDeviceId;
std::vector<audio_io_handle_t> secondaryOutputs;
bool isSpatialized;
bool isBitPerfect;
- ret = AudioSystem::getOutputForAttr(&mAttr, &io,
- mSessionId,
+ mutex().unlock();
+ ret = AudioSystem::getOutputForAttr(&localAttr, &io,
+ localSessionId,
&stream,
adjAttributionSource,
&config,
@@ -10142,6 +10150,8 @@
&secondaryOutputs,
&isSpatialized,
&isBitPerfect);
+ mutex().lock();
+ mAttr = localAttr;
ALOGD_IF(!secondaryOutputs.empty(),
"MmapThread::start does not support secondary outputs, ignoring them");
} else {
@@ -10150,14 +10160,17 @@
config.channel_mask = mChannelMask;
config.format = mFormat;
audio_port_handle_t deviceId = mDeviceId;
- ret = AudioSystem::getInputForAttr(&mAttr, &io,
+ mutex().unlock();
+ ret = AudioSystem::getInputForAttr(&localAttr, &io,
RECORD_RIID_INVALID,
- mSessionId,
+ localSessionId,
adjAttributionSource,
&config,
AUDIO_INPUT_FLAG_MMAP_NOIRQ,
&deviceId,
&portId);
+ mutex().lock();
+ // localAttr is const for getInputForAttr.
}
// APM should not chose a different input or output stream for the same set of attributes
// and audo configuration
@@ -10168,18 +10181,20 @@
}
if (isOutput()) {
+ mutex().unlock();
ret = AudioSystem::startOutput(portId);
+ mutex().lock();
} else {
{
// Add the track record before starting input so that the silent status for the
// client can be cached.
- audio_utils::lock_guard _l(mutex());
setClientSilencedState_l(portId, false /*silenced*/);
}
+ mutex().unlock();
ret = AudioSystem::startInput(portId);
+ mutex().lock();
}
- audio_utils::lock_guard _l(mutex());
// abort if start is rejected by audio policy manager
if (ret != NO_ERROR) {
ALOGE("%s: error start rejected by AudioPolicyManager = %d", __FUNCTION__, ret);
@@ -10223,7 +10238,7 @@
mActiveTracks.add(track);
sp<IAfEffectChain> chain = getEffectChain_l(mSessionId);
if (chain != 0) {
- chain->setStrategy(getStrategyForStream(streamType()));
+ chain->setStrategy(getStrategyForStream(streamType_l()));
chain->incTrackCnt();
chain->incActiveTrackCnt();
}
@@ -10245,18 +10260,17 @@
status_t MmapThread::stop(audio_port_handle_t handle)
{
ALOGV("%s handle %d", __FUNCTION__, handle);
+ audio_utils::lock_guard l(mutex());
if (mHalStream == 0) {
return NO_INIT;
}
if (handle == mPortId) {
- releaseWakeLock();
+ releaseWakeLock_l();
return NO_ERROR;
}
- audio_utils::lock_guard _l(mutex());
-
sp<IAfMmapTrack> track;
for (const sp<IAfMmapTrack>& t : mActiveTracks) {
if (handle == t->portId()) {
@@ -10297,8 +10311,10 @@
}
status_t MmapThread::standby()
+NO_THREAD_SAFETY_ANALYSIS // clang bug
{
ALOGV("%s", __FUNCTION__);
+ audio_utils::lock_guard(mutex());
if (mHalStream == 0) {
return NO_INIT;
@@ -10312,7 +10328,7 @@
mThreadSnapshot.onEnd();
mStandby = true;
}
- releaseWakeLock();
+ releaseWakeLock_l();
return NO_ERROR;
}
@@ -10598,6 +10614,7 @@
}
void MmapThread::toAudioPortConfig(struct audio_port_config* config)
+NO_THREAD_SAFETY_ANALYSIS // mAudioHwDev handle access
{
ThreadBase::toAudioPortConfig(config);
if (isOutput()) {
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 8ac47e7..7fe6143 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -2174,15 +2174,18 @@
void disconnect() final EXCLUDES_ThreadBase_Mutex;
// MmapStreamInterface for adapter.
- status_t createMmapBuffer(int32_t minSizeFrames, struct audio_mmap_buffer_info* info) final;
- status_t getMmapPosition(struct audio_mmap_position* position) const override;
+ status_t createMmapBuffer(int32_t minSizeFrames, struct audio_mmap_buffer_info* info) final
+ EXCLUDES_ThreadBase_Mutex;
+ status_t getMmapPosition(struct audio_mmap_position* position) const override
+ EXCLUDES_ThreadBase_Mutex;
status_t start(const AudioClient& client,
const audio_attributes_t *attr,
audio_port_handle_t* handle) final EXCLUDES_ThreadBase_Mutex;
status_t stop(audio_port_handle_t handle) final EXCLUDES_ThreadBase_Mutex;
status_t standby() final EXCLUDES_ThreadBase_Mutex;
- status_t getExternalPosition(uint64_t* position, int64_t* timeNanos) const = 0;
- status_t reportData(const void* buffer, size_t frameCount) override;
+ status_t getExternalPosition(uint64_t* position, int64_t* timeNanos) const
+ EXCLUDES_ThreadBase_Mutex = 0;
+ status_t reportData(const void* buffer, size_t frameCount) override EXCLUDES_ThreadBase_Mutex;
// RefBase
void onFirstRef() final;
@@ -2211,6 +2214,7 @@
REQUIRES(mutex());
status_t releaseAudioPatch_l(const audio_patch_handle_t handle) final
REQUIRES(mutex());
+ // NO_THREAD_SAFETY_ANALYSIS
void toAudioPortConfig(struct audio_port_config* config) override;
sp<StreamHalInterface> stream() const final { return mHalStream; }
@@ -2231,7 +2235,9 @@
void checkInvalidTracks_l() REQUIRES(mutex());
// Not in ThreadBase
- virtual audio_stream_type_t streamType() const { return AUDIO_STREAM_DEFAULT; }
+ virtual audio_stream_type_t streamType_l() const REQUIRES(mutex()) {
+ return AUDIO_STREAM_DEFAULT;
+ }
virtual void invalidateTracks(audio_stream_type_t /* streamType */)
EXCLUDES_ThreadBase_Mutex {}
void invalidateTracks(std::set<audio_port_handle_t>& /* portIds */) override
@@ -2272,22 +2278,22 @@
/**
* @brief mDeviceId current device port unique identifier
*/
- audio_port_handle_t mDeviceId = AUDIO_PORT_HANDLE_NONE;
+ audio_port_handle_t mDeviceId GUARDED_BY(mutex()) = AUDIO_PORT_HANDLE_NONE;
- audio_attributes_t mAttr;
- audio_session_t mSessionId;
- audio_port_handle_t mPortId;
+ audio_attributes_t mAttr GUARDED_BY(mutex());
+ audio_session_t mSessionId GUARDED_BY(mutex());
+ audio_port_handle_t mPortId GUARDED_BY(mutex());
- wp<MmapStreamCallback> mCallback;
- sp<StreamHalInterface> mHalStream;
- sp<DeviceHalInterface> mHalDevice;
- AudioHwDevice* const mAudioHwDev;
- ActiveTracks<IAfMmapTrack> mActiveTracks;
- float mHalVolFloat;
- std::map<audio_port_handle_t, bool> mClientSilencedStates;
+ wp<MmapStreamCallback> mCallback GUARDED_BY(mutex());
+ sp<StreamHalInterface> mHalStream; // NO_THREAD_SAFETY_ANALYSIS
+ sp<DeviceHalInterface> mHalDevice GUARDED_BY(mutex());
+ AudioHwDevice* const mAudioHwDev GUARDED_BY(mutex());
+ ActiveTracks<IAfMmapTrack> mActiveTracks GUARDED_BY(mutex());
+ float mHalVolFloat GUARDED_BY(mutex());
+ std::map<audio_port_handle_t, bool> mClientSilencedStates GUARDED_BY(mutex());
- int32_t mNoCallbackWarningCount;
- static constexpr int32_t kMaxNoCallbackWarnings = 5;
+ int32_t mNoCallbackWarningCount GUARDED_BY(mutex());
+ static constexpr int32_t kMaxNoCallbackWarnings = 5;
};
class MmapPlaybackThread : public MmapThread, public IAfMmapPlaybackThread,
@@ -2323,8 +2329,7 @@
void invalidateTracks(audio_stream_type_t streamType) final EXCLUDES_ThreadBase_Mutex;
void invalidateTracks(std::set<audio_port_handle_t>& portIds) final EXCLUDES_ThreadBase_Mutex;
- audio_stream_type_t streamType() const final EXCLUDES_ThreadBase_Mutex {
- audio_utils::lock_guard l(mutex());
+ audio_stream_type_t streamType_l() const final REQUIRES(mutex()) {
return mStreamType;
}
void checkSilentMode_l() final REQUIRES(mutex());