AAudio: do not call to aaudio service when the binder has dead.
When aaudio service has dead, the client should not call to service as
its stream handle may be reassigned to a new stream. Instead, when there
is binder death, the stream should be in disconnected state, there
should be an error callback fired.
In AAudioBinderAdapter, it takes a service lifetime id as a reference to
current aaudio service. When there is binder death, the service id will
be increased by 1. When AAudioBinderAdapter finds the service id provided
by the client is different from its own service id, it should reject the
request.
When a MMAP stream is open, it receives a service lifetime id to
recognize the service that it connects to. When processing data, the
client will return AAUDIO_ERROR_DISCONNECTED if current service lifetime
id is different from the one it cached.
Bug: 269531552
Test: repo steps in the bug
Test: atest AAudioTests
Test: oboeservice_fuzzer
Change-Id: Ieddd89fa2e23ad56d34a7fbccb8fb9a70917330e
diff --git a/services/oboeservice/AAudioClientTracker.cpp b/services/oboeservice/AAudioClientTracker.cpp
index c0dac11..c91ead0 100644
--- a/services/oboeservice/AAudioClientTracker.cpp
+++ b/services/oboeservice/AAudioClientTracker.cpp
@@ -196,7 +196,8 @@
for (const auto& serviceStream : streamsToClose) {
const aaudio_handle_t handle = serviceStream->getHandle();
ALOGW("binderDied() close abandoned stream 0x%08X\n", handle);
- aaudioService->asAAudioServiceInterface().closeStream(handle);
+ AAudioHandleInfo handleInfo(DEFAULT_AAUDIO_SERVICE_ID, handle);
+ aaudioService->asAAudioServiceInterface().closeStream(handleInfo);
}
// mStreams should be empty now
}
diff --git a/services/oboeservice/AAudioService.h b/services/oboeservice/AAudioService.h
index df66f1b..ada3d53 100644
--- a/services/oboeservice/AAudioService.h
+++ b/services/oboeservice/AAudioService.h
@@ -36,6 +36,7 @@
namespace android {
#define AAUDIO_SERVICE_NAME "media.aaudio"
+#define DEFAULT_AAUDIO_SERVICE_ID 0
class AAudioService :
public BinderService<AAudioService>,
@@ -108,20 +109,22 @@
private:
class Adapter : public aaudio::AAudioBinderAdapter {
public:
+ // Always use default service id in server side since when crash happens,
+ // the aaudio service will restart.
explicit Adapter(AAudioService *service)
- : aaudio::AAudioBinderAdapter(service),
+ : aaudio::AAudioBinderAdapter(service, DEFAULT_AAUDIO_SERVICE_ID),
mService(service) {}
- aaudio_result_t startClient(aaudio::aaudio_handle_t streamHandle,
+ aaudio_result_t startClient(const aaudio::AAudioHandleInfo& streamHandleInfo,
const android::AudioClient &client,
const audio_attributes_t *attr,
audio_port_handle_t *clientHandle) override {
- return mService->startClient(streamHandle, client, attr, clientHandle);
+ return mService->startClient(streamHandleInfo.getHandle(), client, attr, clientHandle);
}
- aaudio_result_t stopClient(aaudio::aaudio_handle_t streamHandle,
+ aaudio_result_t stopClient(const aaudio::AAudioHandleInfo& streamHandleInfo,
audio_port_handle_t clientHandle) override {
- return mService->stopClient(streamHandle, clientHandle);
+ return mService->stopClient(streamHandleInfo.getHandle(), clientHandle);
}
private:
diff --git a/services/oboeservice/fuzzer/oboeservice_fuzzer.cpp b/services/oboeservice/fuzzer/oboeservice_fuzzer.cpp
index 6dc6eff..f047065 100644
--- a/services/oboeservice/fuzzer/oboeservice_fuzzer.cpp
+++ b/services/oboeservice/fuzzer/oboeservice_fuzzer.cpp
@@ -149,41 +149,42 @@
void registerClient(const sp<IAAudioClient> &client UNUSED_PARAM) override {}
- aaudio_handle_t openStream(const AAudioStreamRequest &request,
- AAudioStreamConfiguration &configurationOutput) override;
+ AAudioHandleInfo openStream(const AAudioStreamRequest &request,
+ AAudioStreamConfiguration &configurationOutput) override;
- aaudio_result_t closeStream(aaudio_handle_t streamHandle) override;
+ aaudio_result_t closeStream(const AAudioHandleInfo& streamHandleInfo) override;
- aaudio_result_t getStreamDescription(aaudio_handle_t streamHandle,
+ aaudio_result_t getStreamDescription(const AAudioHandleInfo& streamHandleInfo,
AudioEndpointParcelable &parcelable) override;
- aaudio_result_t startStream(aaudio_handle_t streamHandle) override;
+ aaudio_result_t startStream(const AAudioHandleInfo& streamHandleInfo) override;
- aaudio_result_t pauseStream(aaudio_handle_t streamHandle) override;
+ aaudio_result_t pauseStream(const AAudioHandleInfo& streamHandleInfo) override;
- aaudio_result_t stopStream(aaudio_handle_t streamHandle) override;
+ aaudio_result_t stopStream(const AAudioHandleInfo& streamHandleInfo) override;
- aaudio_result_t flushStream(aaudio_handle_t streamHandle) override;
+ aaudio_result_t flushStream(const AAudioHandleInfo& streamHandleInfo) override;
- aaudio_result_t registerAudioThread(aaudio_handle_t streamHandle, pid_t clientThreadId,
+ aaudio_result_t registerAudioThread(const AAudioHandleInfo& streamHandleInfo,
+ pid_t clientThreadId,
int64_t periodNanoseconds) override;
- aaudio_result_t unregisterAudioThread(aaudio_handle_t streamHandle,
+ aaudio_result_t unregisterAudioThread(const AAudioHandleInfo& streamHandleInfo,
pid_t clientThreadId) override;
- aaudio_result_t startClient(aaudio_handle_t streamHandle UNUSED_PARAM,
+ aaudio_result_t startClient(const AAudioHandleInfo& streamHandleInfo UNUSED_PARAM,
const AudioClient &client UNUSED_PARAM,
const audio_attributes_t *attr UNUSED_PARAM,
audio_port_handle_t *clientHandle UNUSED_PARAM) override {
return AAUDIO_ERROR_UNAVAILABLE;
}
- aaudio_result_t stopClient(aaudio_handle_t streamHandle UNUSED_PARAM,
+ aaudio_result_t stopClient(const AAudioHandleInfo& streamHandleInfo UNUSED_PARAM,
audio_port_handle_t clientHandle UNUSED_PARAM) override {
return AAUDIO_ERROR_UNAVAILABLE;
}
- aaudio_result_t exitStandby(aaudio_handle_t streamHandle UNUSED_PARAM,
+ aaudio_result_t exitStandby(const AAudioHandleInfo& streamHandleInfo UNUSED_PARAM,
AudioEndpointParcelable &parcelable UNUSED_PARAM) override {
return AAUDIO_ERROR_UNAVAILABLE;
}
@@ -250,92 +251,91 @@
mAAudioService.clear();
}
-aaudio_handle_t FuzzAAudioClient::openStream(const AAudioStreamRequest &request,
- AAudioStreamConfiguration &configurationOutput) {
- aaudio_handle_t stream;
+AAudioHandleInfo FuzzAAudioClient::openStream(const AAudioStreamRequest &request,
+ AAudioStreamConfiguration &configurationOutput) {
for (int i = 0; i < 2; ++i) {
AAudioServiceInterface *service = getAAudioService();
if (!service) {
- return AAUDIO_ERROR_NO_SERVICE;
+ return {-1, AAUDIO_ERROR_NO_SERVICE};
}
- stream = service->openStream(request, configurationOutput);
+ auto streamHandleInfo = service->openStream(request, configurationOutput);
- if (stream == AAUDIO_ERROR_NO_SERVICE) {
+ if (streamHandleInfo.getHandle() == AAUDIO_ERROR_NO_SERVICE) {
dropAAudioService();
} else {
- break;
+ return streamHandleInfo;
}
}
- return stream;
+ return {-1, AAUDIO_ERROR_NO_SERVICE};
}
-aaudio_result_t FuzzAAudioClient::closeStream(aaudio_handle_t streamHandle) {
+aaudio_result_t FuzzAAudioClient::closeStream(const AAudioHandleInfo& streamHandleInfo) {
AAudioServiceInterface *service = getAAudioService();
if (!service) {
return AAUDIO_ERROR_NO_SERVICE;
}
- return service->closeStream(streamHandle);
+ return service->closeStream(streamHandleInfo);
}
-aaudio_result_t FuzzAAudioClient::getStreamDescription(aaudio_handle_t streamHandle,
+aaudio_result_t FuzzAAudioClient::getStreamDescription(const AAudioHandleInfo& streamHandleInfo,
AudioEndpointParcelable &parcelable) {
AAudioServiceInterface *service = getAAudioService();
if (!service) {
return AAUDIO_ERROR_NO_SERVICE;
}
- return service->getStreamDescription(streamHandle, parcelable);
+ return service->getStreamDescription(streamHandleInfo, parcelable);
}
-aaudio_result_t FuzzAAudioClient::startStream(aaudio_handle_t streamHandle) {
+aaudio_result_t FuzzAAudioClient::startStream(const AAudioHandleInfo& streamHandleInfo) {
AAudioServiceInterface *service = getAAudioService();
if (!service) {
return AAUDIO_ERROR_NO_SERVICE;
}
- return service->startStream(streamHandle);
+ return service->startStream(streamHandleInfo);
}
-aaudio_result_t FuzzAAudioClient::pauseStream(aaudio_handle_t streamHandle) {
+aaudio_result_t FuzzAAudioClient::pauseStream(const AAudioHandleInfo& streamHandleInfo) {
AAudioServiceInterface *service = getAAudioService();
if (!service) {
return AAUDIO_ERROR_NO_SERVICE;
}
- return service->pauseStream(streamHandle);
+ return service->pauseStream(streamHandleInfo);
}
-aaudio_result_t FuzzAAudioClient::stopStream(aaudio_handle_t streamHandle) {
+aaudio_result_t FuzzAAudioClient::stopStream(const AAudioHandleInfo& streamHandleInfo) {
AAudioServiceInterface *service = getAAudioService();
if (!service) {
return AAUDIO_ERROR_NO_SERVICE;
}
- return service->stopStream(streamHandle);
+ return service->stopStream(streamHandleInfo);
}
-aaudio_result_t FuzzAAudioClient::flushStream(aaudio_handle_t streamHandle) {
+aaudio_result_t FuzzAAudioClient::flushStream(const AAudioHandleInfo& streamHandleInfo) {
AAudioServiceInterface *service = getAAudioService();
if (!service) {
return AAUDIO_ERROR_NO_SERVICE;
}
- return service->flushStream(streamHandle);
+ return service->flushStream(streamHandleInfo);
}
-aaudio_result_t FuzzAAudioClient::registerAudioThread(aaudio_handle_t streamHandle,
+aaudio_result_t FuzzAAudioClient::registerAudioThread(const AAudioHandleInfo& streamHandleInfo,
pid_t clientThreadId,
int64_t periodNanoseconds) {
AAudioServiceInterface *service = getAAudioService();
if (!service) {
return AAUDIO_ERROR_NO_SERVICE;
}
- return service->registerAudioThread(streamHandle, clientThreadId, periodNanoseconds);
+ return service->registerAudioThread(streamHandleInfo, clientThreadId, periodNanoseconds);
}
-aaudio_result_t FuzzAAudioClient::unregisterAudioThread(aaudio_handle_t streamHandle,
+aaudio_result_t FuzzAAudioClient::unregisterAudioThread(const AAudioHandleInfo& streamHandleInfo,
pid_t clientThreadId) {
AAudioServiceInterface *service = getAAudioService();
if (!service) {
return AAUDIO_ERROR_NO_SERVICE;
}
- return service->unregisterAudioThread(streamHandle, clientThreadId);
+ return service->unregisterAudioThread(streamHandleInfo, clientThreadId);
}
class OboeserviceFuzzer {
@@ -410,8 +410,8 @@
? fdp.ConsumeIntegral<int32_t>()
: kAAudioFormats[fdp.ConsumeIntegralInRange<int32_t>(0, kNumAAudioFormats - 1)]));
- aaudio_handle_t stream = mClient->openStream(request, configurationOutput);
- if (stream < 0) {
+ auto streamHandleInfo = mClient->openStream(request, configurationOutput);
+ if (streamHandleInfo.getHandle() < 0) {
// invalid request, stream not opened.
return;
}
@@ -420,23 +420,23 @@
int action = fdp.ConsumeIntegralInRange<int32_t>(0, 4);
switch (action) {
case 0:
- mClient->getStreamDescription(stream, audioEndpointParcelable);
+ mClient->getStreamDescription(streamHandleInfo, audioEndpointParcelable);
break;
case 1:
- mClient->startStream(stream);
+ mClient->startStream(streamHandleInfo);
break;
case 2:
- mClient->pauseStream(stream);
+ mClient->pauseStream(streamHandleInfo);
break;
case 3:
- mClient->stopStream(stream);
+ mClient->stopStream(streamHandleInfo);
break;
case 4:
- mClient->flushStream(stream);
+ mClient->flushStream(streamHandleInfo);
break;
}
}
- mClient->closeStream(stream);
+ mClient->closeStream(streamHandleInfo);
assert(mClient->getDeathCount() == 0);
}