Use cached invalid tracks id when checking invalid tracks.

When checking invalid tracks, audio flinger will need to call the
callback if it exists. This need to be done without the lock in case it
takes a long time. However, after unlocking, the list of tracks can
already be modified. This can cause unexpected crash. To resolve the
issue, make a copy of the invalid tracks id under lock and call the
callback outside of the lock.

Test: OboeTester test disconnect
Bug: 228582029
Change-Id: I6fe28fa097acb91f4081666bad8289eae1c62c6e
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index d1d359c..e1c4b5a 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -10280,19 +10280,28 @@
 
 void AudioFlinger::MmapThread::checkInvalidTracks_l()
 {
+    std::vector<audio_port_handle_t> invalidPortIds;
     for (const sp<MmapTrack> &track : mActiveTracks) {
         if (track->isInvalid()) {
-            sp<MmapStreamCallback> callback = mCallback.promote();
-            if (callback != 0) {
-                mLock.unlock();
-                callback->onTearDown(track->portId());
-                mLock.lock();
-            } else if (mNoCallbackWarningCount < kMaxNoCallbackWarnings) {
-                ALOGW("Could not notify MMAP stream tear down: no onTearDown callback!");
-                mNoCallbackWarningCount++;
-            }
+            invalidPortIds.push_back(track->portId());
         }
     }
+    if (invalidPortIds.empty()) {
+        return;
+    }
+    sp<MmapStreamCallback> callback = mCallback.promote();
+    if (callback == nullptr) {
+        if (mNoCallbackWarningCount < kMaxNoCallbackWarnings) {
+            ALOGW("Could not notify MMAP stream tear down: no onTearDown callback!");
+            mNoCallbackWarningCount++;
+        }
+        return;
+    }
+    mLock.unlock();
+    for (const auto invalidPortId : invalidPortIds) {
+        callback->onTearDown(invalidPortId);
+    }
+    mLock.lock();
 }
 
 void AudioFlinger::MmapThread::dumpInternals_l(int fd, const Vector<String16>& args __unused)