aaudio service: prevent disconnected endpoints from being used
Also close the internal stream used by AAudioServiceEndpointShared.
This prevents a resource leak caused by an app not closing a
disconnected stream.
It also prevents an app from reopening a device that was just
disconnected.
Bug: 67664976
Test: test_bad_disconnect.cpp should get new device ID after disconnect
Change-Id: I9a234b5704d62af788064fdd352b63181ad7e559
diff --git a/services/oboeservice/AAudioServiceEndpoint.cpp b/services/oboeservice/AAudioServiceEndpoint.cpp
index 3095bc9..f917675 100644
--- a/services/oboeservice/AAudioServiceEndpoint.cpp
+++ b/services/oboeservice/AAudioServiceEndpoint.cpp
@@ -60,6 +60,7 @@
result << " Reference Count: " << mOpenCount << "\n";
result << " Requested Device Id: " << mRequestedDeviceId << "\n";
result << " Device Id: " << getDeviceId() << "\n";
+ result << " Connected: " << mConnected.load() << "\n";
result << " Registered Streams:" << "\n";
result << AAudioServiceStreamShared::dumpHeader() << "\n";
for (const auto stream : mRegisteredStreams) {
@@ -74,7 +75,9 @@
void AAudioServiceEndpoint::disconnectRegisteredStreams() {
std::lock_guard<std::mutex> lock(mLockStreams);
+ mConnected.store(false);
for (const auto stream : mRegisteredStreams) {
+ ALOGD("disconnectRegisteredStreams() stop and disconnect %p", stream.get());
stream->stop();
stream->disconnect();
}
@@ -96,6 +99,9 @@
}
bool AAudioServiceEndpoint::matches(const AAudioStreamConfiguration& configuration) {
+ if (!mConnected.load()) {
+ return false; // Only use an endpoint if it is connected to a device.
+ }
if (configuration.getDirection() != getDirection()) {
return false;
}
diff --git a/services/oboeservice/AAudioServiceEndpoint.h b/services/oboeservice/AAudioServiceEndpoint.h
index 2ef6234..6312c51 100644
--- a/services/oboeservice/AAudioServiceEndpoint.h
+++ b/services/oboeservice/AAudioServiceEndpoint.h
@@ -97,6 +97,10 @@
mOpenCount = count;
}
+ bool isConnected() const {
+ return mConnected;
+ }
+
protected:
void disconnectRegisteredStreams();
@@ -111,6 +115,8 @@
int32_t mOpenCount = 0;
int32_t mRequestedDeviceId = 0;
+ std::atomic<bool> mConnected{true};
+
};
} /* namespace aaudio */
diff --git a/services/oboeservice/AAudioServiceEndpointShared.cpp b/services/oboeservice/AAudioServiceEndpointShared.cpp
index cd40066..820ed28 100644
--- a/services/oboeservice/AAudioServiceEndpointShared.cpp
+++ b/services/oboeservice/AAudioServiceEndpointShared.cpp
@@ -91,7 +91,12 @@
static void *aaudio_endpoint_thread_proc(void *context) {
AAudioServiceEndpointShared *endpoint = (AAudioServiceEndpointShared *) context;
if (endpoint != NULL) {
- return endpoint->callbackLoop();
+ void *result = endpoint->callbackLoop();
+ // Close now so that the HW resource is freed and we can open a new device.
+ if (!endpoint->isConnected()) {
+ endpoint->close();
+ }
+ return result;
} else {
return NULL;
}