AudioFlinger: Forward track port volume to patch tracks

Test:  atest AudioPlaybackCaptureTest (no apparent regressions)
Bug: 317212590
Flag: EXEMPT bugfix
Change-Id: Icff568f7764c9cf4752317707cac3c6e2121edfd
diff --git a/services/audioflinger/PlaybackTracks.h b/services/audioflinger/PlaybackTracks.h
index 3edeee3..84758a4 100644
--- a/services/audioflinger/PlaybackTracks.h
+++ b/services/audioflinger/PlaybackTracks.h
@@ -225,9 +225,7 @@
     void setInternalMute(bool muted) final { mInternalMute = muted; }
 
     // VolumePortInterface implementation
-    void setPortVolume(float volume) override {
-        mVolume = volume;
-    }
+    void setPortVolume(float volume) override;
     float getPortVolume() const override { return mVolume; }
 
 protected:
@@ -414,7 +412,7 @@
     std::unique_ptr<os::PersistableBundle> mMuteEventExtras;
     mute_state_t        mMuteState;
     bool                mInternalMute = false;
-    float mVolume = 0.0f;
+    std::atomic<float> mVolume = 0.0f;
 };  // end of Track
 
 
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 51e140d..5aa58a2 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -1601,6 +1601,16 @@
     return INVALID_OPERATION;
 }
 
+void Track::setPortVolume(float volume) {
+    mVolume = volume;
+    if (mType != TYPE_PATCH) {
+        // Do not recursively propagate a PatchTrack setPortVolume to
+        // downstream PatchTracks.
+        forEachTeePatchTrack_l([volume](const auto& patchTrack) {
+                patchTrack->setPortVolume(volume); });
+    }
+}
+
 VolumeShaper::Status Track::applyVolumeShaper(
         const sp<VolumeShaper::Configuration>& configuration,
         const sp<VolumeShaper::Operation>& operation)