aaudio: disable exclusive mode after steal

Prevent a process that had its exclusive stream stolen
from obtaining another exclusive stream.
This can prevent a collision between two processes after
they both try to open EXCLUSIVE streams after
a DISCONNECT event.

Bug: 157777324
Test: adb shell test_steal_exclusive -r0 -d100
Change-Id: I0fe12be95a8fbd05ed03f10796e1ca716025c885
diff --git a/services/oboeservice/AAudioEndpointManager.cpp b/services/oboeservice/AAudioEndpointManager.cpp
index c9bf72f..9f34153 100644
--- a/services/oboeservice/AAudioEndpointManager.cpp
+++ b/services/oboeservice/AAudioEndpointManager.cpp
@@ -25,6 +25,7 @@
 #include <sstream>
 #include <utility/AAudioUtilities.h>
 
+#include "AAudioClientTracker.h"
 #include "AAudioEndpointManager.h"
 #include "AAudioServiceEndpointShared.h"
 #include "AAudioServiceEndpointMMAP.h"
@@ -174,7 +175,15 @@
                 && !request.isSharingModeMatchRequired()) { // app did not request a shared stream
             ALOGD("%s() endpoint in EXCLUSIVE use. Steal it!", __func__);
             mExclusiveStolenCount++;
-            endpointToSteal = endpoint;
+            // Prevent this process from getting another EXCLUSIVE stream.
+            // This will prevent two clients from colliding after a DISCONNECTION
+            // when they both try to open an exclusive stream at the same time.
+            // That can result in a stream getting disconnected between the OPEN
+            // and START calls. This will help preserve app compatibility.
+            // An app can avoid having this happen by closing their streams when
+            // the app is paused.
+            AAudioClientTracker::getInstance().setExclusiveEnabled(request.getProcessId(), false);
+            endpointToSteal = endpoint; // return it to caller
         }
         return nullptr;
     } else {