audioflinger: fire routing changed to mmap clients before creating patch
For mmap streams, they will be disconnected and the client is required
to reopen the stream when the routing is changed. In that case, it is
safe to fire the routing changed to mmap clients before patch creation
arrive the HAL.
Bug: 325129412
Test: Test disconnect with OboeTester
Test: Connect/Disconnect USB device with DrumThumper
Change-Id: Icfd9e93a81bb28b427a95f4dc1fa565b5f98e1a4
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 9018dcc..1473bc4 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -10663,6 +10663,16 @@
}
}
+ // For mmap streams, once the routing has changed, they will be disconnected. It should be
+ // okay to notify the client earlier before the new patch creation.
+ if (mDeviceId != deviceId) {
+ if (const sp<MmapStreamCallback> callback = mCallback.promote()) {
+ // The aaudioservice handle the routing changed event asynchronously. In that case,
+ // it is safe to hold the lock here.
+ callback->onRoutingChanged(deviceId);
+ }
+ }
+
if (mAudioHwDev->supportsAudioPatches()) {
status = mHalDevice->createAudioPatch(patch->num_sources, patch->sources, patch->num_sinks,
patch->sinks, handle);
@@ -10688,12 +10698,6 @@
sendIoConfigEvent_l(AUDIO_INPUT_CONFIG_CHANGED);
mInDeviceTypeAddr = sourceDeviceTypeAddr;
}
- sp<MmapStreamCallback> callback = mCallback.promote();
- if (mDeviceId != deviceId && callback != 0) {
- mutex().unlock();
- callback->onRoutingChanged(deviceId);
- mutex().lock();
- }
mPatch = *patch;
mDeviceId = deviceId;
}
@@ -10845,22 +10849,19 @@
void MmapThread::checkInvalidTracks_l()
{
- sp<MmapStreamCallback> callback;
for (const sp<IAfMmapTrack>& track : mActiveTracks) {
if (track->isInvalid()) {
- callback = mCallback.promote();
- if (callback == nullptr && mNoCallbackWarningCount < kMaxNoCallbackWarnings) {
+ if (const sp<MmapStreamCallback> callback = mCallback.promote()) {
+ // The aaudioservice handle the routing changed event asynchronously. In that case,
+ // it is safe to hold the lock here.
+ callback->onRoutingChanged(AUDIO_PORT_HANDLE_NONE);
+ } else if (mNoCallbackWarningCount < kMaxNoCallbackWarnings) {
ALOGW("Could not notify MMAP stream tear down: no onRoutingChanged callback!");
mNoCallbackWarningCount++;
}
break;
}
}
- if (callback != 0) {
- mutex().unlock();
- callback->onRoutingChanged(AUDIO_PORT_HANDLE_NONE);
- mutex().lock();
- }
}
void MmapThread::dumpInternals_l(int fd, const Vector<String16>& /* args */)