audioflinger: fix recursive mutex locking

Commit 3e1acc0c5 introduced a possible recursive mutex locking when
an AudioRecord creation request with FAST flag is rejected by
AudioFlinger after the input was opened by audio policy.

Bug: 70388312
Test: AudioRecord CTS, Audio smoke tests
Change-Id: Ifc835fddd7e819600a834a8d058a9c98bddbee4e
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index aeb32bb..9fef60f 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1585,6 +1585,7 @@
 
     output.cblk.clear();
     output.buffers.clear();
+    output.inputId = AUDIO_IO_HANDLE_NONE;
 
     bool updatePid = (input.clientInfo.clientPid == -1);
     const uid_t callingUid = IPCThreadState::self()->getCallingUid();
@@ -1633,7 +1634,6 @@
     }
 
     output.sessionId = sessionId;
-    output.inputId = AUDIO_IO_HANDLE_NONE;
     output.selectedDeviceId = input.selectedDeviceId;
     output.flags = input.flags;
 
@@ -1645,6 +1645,12 @@
     // The sp<> references will be dropped when re-entering scope.
     // The lack of indentation is deliberate, to reduce code churn and ease merges.
     for (;;) {
+    // release previously opened input if retrying.
+    if (output.inputId != AUDIO_IO_HANDLE_NONE) {
+        recordTrack.clear();
+        AudioSystem::releaseInput(output.inputId, sessionId);
+        output.inputId = AUDIO_IO_HANDLE_NONE;
+    }
     lStatus = AudioSystem::getInputForAttr(&input.attr, &output.inputId,
                                       sessionId,
                                     // FIXME compare to AudioTrack
@@ -1680,13 +1686,10 @@
         // lStatus == BAD_TYPE means FAST flag was rejected: request a new input from
         // audio policy manager without FAST constraint
         if (lStatus == BAD_TYPE) {
-            AudioSystem::releaseInput(output.inputId, sessionId);
-            recordTrack.clear();
             continue;
         }
 
         if (lStatus != NO_ERROR) {
-            recordTrack.clear();
             goto Exit;
         }
 
@@ -1719,6 +1722,10 @@
             Mutex::Autolock _cl(mClientLock);
             client.clear();
         }
+        recordTrack.clear();
+        if (output.inputId != AUDIO_IO_HANDLE_NONE) {
+            AudioSystem::releaseInput(output.inputId, sessionId);
+        }
     }
 
     *status = lStatus;