PatchPanel: Keep peer alive during use.
Test: BT call, switch from hearing aid to headset
Bug: 126789266
Change-Id: I589e5ecaac25c1ce1d504a387662b96cf50f63ba
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 4033247..213c9c3 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -836,8 +836,10 @@
}
teePatches.push_back({patchRecord, patchTrack});
secondaryThread->addPatchTrack(patchTrack);
- patchTrack->setPeerProxy(patchRecord.get());
- patchRecord->setPeerProxy(patchTrack.get());
+ // In case the downstream patchTrack on the secondaryThread temporarily outlives
+ // our created track, ensure the corresponding patchRecord is still alive.
+ patchTrack->setPeerProxy(patchRecord, true /* holdReference */);
+ patchRecord->setPeerProxy(patchTrack, false /* holdReference */);
}
track->setTeePatches(std::move(teePatches));
}
diff --git a/services/audioflinger/PatchPanel.cpp b/services/audioflinger/PatchPanel.cpp
index 676a575..13243b8 100644
--- a/services/audioflinger/PatchPanel.cpp
+++ b/services/audioflinger/PatchPanel.cpp
@@ -527,8 +527,8 @@
}
// tie playback and record tracks together
- mRecord.setTrackAndPeer(tempRecordTrack, tempPatchTrack.get());
- mPlayback.setTrackAndPeer(tempPatchTrack, tempRecordTrack.get());
+ mRecord.setTrackAndPeer(tempRecordTrack, tempPatchTrack);
+ mPlayback.setTrackAndPeer(tempPatchTrack, tempRecordTrack);
// start capture and playback
mRecord.track()->start(AudioSystem::SYNC_EVENT_NONE, AUDIO_SESSION_NONE);
@@ -543,6 +543,7 @@
__func__, mRecord.handle(), mPlayback.handle());
mRecord.stopTrack();
mPlayback.stopTrack();
+ mRecord.track()->clearPeerProxy(); // mRecord stop is synchronous. Break PeerProxy sp<> cycle.
mRecord.closeConnections(panel);
mPlayback.closeConnections(panel);
}
diff --git a/services/audioflinger/PatchPanel.h b/services/audioflinger/PatchPanel.h
index 612855f..aba2cc2 100644
--- a/services/audioflinger/PatchPanel.h
+++ b/services/audioflinger/PatchPanel.h
@@ -122,11 +122,11 @@
mThread = thread;
mCloseThread = closeThread;
}
- void setTrackAndPeer(const sp<TrackType>& track,
- ThreadBase::PatchProxyBufferProvider *peer) {
+ template <typename T>
+ void setTrackAndPeer(const sp<TrackType>& track, const sp<T> &peer) {
mTrack = track;
mThread->addPatchTrack(mTrack);
- mTrack->setPeerProxy(peer);
+ mTrack->setPeerProxy(peer, true /* holdReference */);
}
void stopTrack() { if (mTrack) mTrack->stop(); }
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index f4a31ed..49f74a2 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -7683,6 +7683,8 @@
// note that threadLoop may still be processing the track at this point [without lock]
recordTrack->mState = TrackBase::PAUSING;
+ // NOTE: Waiting here is important to keep stop synchronous.
+ // This is needed for proper patchRecord peer release.
while (recordTrack->mState == TrackBase::PAUSING && !recordTrack->isInvalid()) {
mWaitWorkCV.broadcast(); // signal thread to stop
mStartStopCond.wait(mLock);
diff --git a/services/audioflinger/TrackBase.h b/services/audioflinger/TrackBase.h
index 0ba0ab4..e23173f 100644
--- a/services/audioflinger/TrackBase.h
+++ b/services/audioflinger/TrackBase.h
@@ -337,10 +337,19 @@
PatchTrackBase(sp<ClientProxy> proxy, const ThreadBase& thread,
const Timeout& timeout);
void setPeerTimeout(std::chrono::nanoseconds timeout);
- void setPeerProxy(PatchProxyBufferProvider *proxy) { mPeerProxy = proxy; }
+ template <typename T>
+ void setPeerProxy(const sp<T> &proxy, bool holdReference) {
+ mPeerReferenceHold = holdReference ? proxy : nullptr;
+ mPeerProxy = proxy.get();
+ }
+ void clearPeerProxy() {
+ mPeerReferenceHold.clear();
+ mPeerProxy = nullptr;
+ }
protected:
const sp<ClientProxy> mProxy;
+ sp<RefBase> mPeerReferenceHold; // keeps mPeerProxy alive during access.
PatchProxyBufferProvider* mPeerProxy = nullptr;
struct timespec mPeerTimeout{};
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index ad78a45..5a43696 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -1723,6 +1723,7 @@
AudioFlinger::PlaybackThread::PatchTrack::~PatchTrack()
{
+ ALOGV("%s(%d)", __func__, mId);
}
status_t AudioFlinger::PlaybackThread::PatchTrack::start(AudioSystem::sync_event_t event,
@@ -2193,6 +2194,7 @@
AudioFlinger::RecordThread::PatchRecord::~PatchRecord()
{
+ ALOGV("%s(%d)", __func__, mId);
}
// AudioBufferProvider interface