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());