aaudio: close MMAP stream if client dies
Notify client when audio service dies. Clear connection.
Notify AAudio service when client dies. Close client streams.
Use sp<> to track ServiceStreams.
Bug: 38267698
Test: test_no_close.cpp
Change-Id: I5f1699ed3b8b7bd960947c0028a89ca8419ce7a0
diff --git a/media/libaaudio/src/binding/IAAudioService.cpp b/media/libaaudio/src/binding/IAAudioService.cpp
index e4bf82a..97fbaaa 100644
--- a/media/libaaudio/src/binding/IAAudioService.cpp
+++ b/media/libaaudio/src/binding/IAAudioService.cpp
@@ -14,6 +14,10 @@
* limitations under the License.
*/
+#define LOG_TAG "AAudio"
+//#define LOG_NDEBUG 0
+#include <utils/Log.h>
+
#include <aaudio/AAudio.h>
#include <binder/IPCThreadState.h>
@@ -41,8 +45,16 @@
{
}
- virtual aaudio_handle_t openStream(const aaudio::AAudioStreamRequest &request,
- aaudio::AAudioStreamConfiguration &configurationOutput) override {
+ void registerClient(const sp<IAAudioClient>& client) override
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
+ data.writeStrongBinder(IInterface::asBinder(client));
+ remote()->transact(REGISTER_CLIENT, data, &reply);
+ }
+
+ aaudio_handle_t openStream(const aaudio::AAudioStreamRequest &request,
+ aaudio::AAudioStreamConfiguration &configurationOutput) override {
Parcel data, reply;
// send command
data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
@@ -56,7 +68,6 @@
// parse reply
aaudio_handle_t stream;
err = reply.readInt32(&stream);
- ALOGD("BpAAudioService::client openStream returned stream = 0x%08x", stream);
if (err != NO_ERROR) {
ALOGE("BpAAudioService::client transact(OPEN_STREAM) readInt %d", err);
return AAudioConvert_androidToAAudioResult(err);
@@ -233,7 +244,7 @@
status_t BnAAudioService::onTransact(uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags) {
- aaudio_handle_t stream;
+ aaudio_handle_t streamHandle;
aaudio::AAudioStreamRequest request;
aaudio::AAudioStreamConfiguration configuration;
pid_t tid;
@@ -242,6 +253,14 @@
ALOGV("BnAAudioService::onTransact(%i) %i", code, flags);
switch(code) {
+ case REGISTER_CLIENT: {
+ CHECK_INTERFACE(IAAudioService, data, reply);
+ sp<IAAudioClient> client = interface_cast<IAAudioClient>(
+ data.readStrongBinder());
+ registerClient(client);
+ return NO_ERROR;
+ } break;
+
case OPEN_STREAM: {
CHECK_INTERFACE(IAAudioService, data, reply);
request.readFromParcel(&data);
@@ -250,28 +269,28 @@
// Override the uid and pid from the client in case they are incorrect.
request.setUserId(IPCThreadState::self()->getCallingUid());
request.setProcessId(IPCThreadState::self()->getCallingPid());
- stream = openStream(request, configuration);
- //ALOGD("BnAAudioService::onTransact OPEN_STREAM server handle = 0x%08X ----", stream);
- reply->writeInt32(stream);
+ streamHandle = openStream(request, configuration);
+ //ALOGD("BnAAudioService::onTransact OPEN_STREAM server handle = 0x%08X", streamHandle);
+ reply->writeInt32(streamHandle);
configuration.writeToParcel(reply);
return NO_ERROR;
} break;
case CLOSE_STREAM: {
CHECK_INTERFACE(IAAudioService, data, reply);
- data.readInt32(&stream);
- result = closeStream(stream);
+ data.readInt32(&streamHandle);
+ result = closeStream(streamHandle);
//ALOGD("BnAAudioService::onTransact CLOSE_STREAM 0x%08X, result = %d",
- // stream, result);
+ // streamHandle, result);
reply->writeInt32(result);
return NO_ERROR;
} break;
case GET_STREAM_DESCRIPTION: {
CHECK_INTERFACE(IAAudioService, data, reply);
- data.readInt32(&stream);
+ data.readInt32(&streamHandle);
aaudio::AudioEndpointParcelable parcelable;
- result = getStreamDescription(stream, parcelable);
+ result = getStreamDescription(streamHandle, parcelable);
if (result != AAUDIO_OK) {
return AAudioConvert_aaudioToAndroidStatus(result);
}
@@ -288,63 +307,63 @@
case START_STREAM: {
CHECK_INTERFACE(IAAudioService, data, reply);
- data.readInt32(&stream);
- result = startStream(stream);
+ data.readInt32(&streamHandle);
+ result = startStream(streamHandle);
ALOGV("BnAAudioService::onTransact START_STREAM 0x%08X, result = %d",
- stream, result);
+ streamHandle, result);
reply->writeInt32(result);
return NO_ERROR;
} break;
case PAUSE_STREAM: {
CHECK_INTERFACE(IAAudioService, data, reply);
- data.readInt32(&stream);
- result = pauseStream(stream);
+ data.readInt32(&streamHandle);
+ result = pauseStream(streamHandle);
ALOGV("BnAAudioService::onTransact PAUSE_STREAM 0x%08X, result = %d",
- stream, result);
+ streamHandle, result);
reply->writeInt32(result);
return NO_ERROR;
} break;
case STOP_STREAM: {
CHECK_INTERFACE(IAAudioService, data, reply);
- data.readInt32(&stream);
- result = stopStream(stream);
+ data.readInt32(&streamHandle);
+ result = stopStream(streamHandle);
ALOGV("BnAAudioService::onTransact STOP_STREAM 0x%08X, result = %d",
- stream, result);
+ streamHandle, result);
reply->writeInt32(result);
return NO_ERROR;
} break;
case FLUSH_STREAM: {
CHECK_INTERFACE(IAAudioService, data, reply);
- data.readInt32(&stream);
- result = flushStream(stream);
+ data.readInt32(&streamHandle);
+ result = flushStream(streamHandle);
ALOGV("BnAAudioService::onTransact FLUSH_STREAM 0x%08X, result = %d",
- stream, result);
+ streamHandle, result);
reply->writeInt32(result);
return NO_ERROR;
} break;
case REGISTER_AUDIO_THREAD: {
CHECK_INTERFACE(IAAudioService, data, reply);
- data.readInt32(&stream);
+ data.readInt32(&streamHandle);
data.readInt32(&tid);
data.readInt64(&nanoseconds);
- result = registerAudioThread(stream, tid, nanoseconds);
+ result = registerAudioThread(streamHandle, tid, nanoseconds);
ALOGV("BnAAudioService::onTransact REGISTER_AUDIO_THREAD 0x%08X, result = %d",
- stream, result);
+ streamHandle, result);
reply->writeInt32(result);
return NO_ERROR;
} break;
case UNREGISTER_AUDIO_THREAD: {
CHECK_INTERFACE(IAAudioService, data, reply);
- data.readInt32(&stream);
+ data.readInt32(&streamHandle);
data.readInt32(&tid);
- result = unregisterAudioThread(stream, tid);
+ result = unregisterAudioThread(streamHandle, tid);
ALOGV("BnAAudioService::onTransact UNREGISTER_AUDIO_THREAD 0x%08X, result = %d",
- stream, result);
+ streamHandle, result);
reply->writeInt32(result);
return NO_ERROR;
} break;