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/media/libaaudio/src/binding/AAudioBinderAdapter.cpp b/media/libaaudio/src/binding/AAudioBinderAdapter.cpp
index 42d81ca..ee7480b 100644
--- a/media/libaaudio/src/binding/AAudioBinderAdapter.cpp
+++ b/media/libaaudio/src/binding/AAudioBinderAdapter.cpp
@@ -23,15 +23,16 @@
using android::aidl_utils::statusTFromBinderStatus;
using android::binder::Status;
-AAudioBinderAdapter::AAudioBinderAdapter(IAAudioService* delegate)
- : mDelegate(delegate) {}
+AAudioBinderAdapter::AAudioBinderAdapter(IAAudioService* delegate,
+ int32_t serviceLifetimeId)
+ : mDelegate(delegate), mServiceLifetimeId(serviceLifetimeId) {}
void AAudioBinderAdapter::registerClient(const android::sp<IAAudioClient>& client) {
mDelegate->registerClient(client);
}
-aaudio_handle_t AAudioBinderAdapter::openStream(const AAudioStreamRequest& request,
- AAudioStreamConfiguration& config) {
+AAudioHandleInfo AAudioBinderAdapter::openStream(const AAudioStreamRequest& request,
+ AAudioStreamConfiguration& config) {
aaudio_handle_t result;
StreamParameters params;
Status status = mDelegate->openStream(request.parcelable(),
@@ -41,23 +42,29 @@
result = AAudioConvert_androidToAAudioResult(statusTFromBinderStatus(status));
}
config = params;
- return result;
+ return {mServiceLifetimeId, result};
}
-aaudio_result_t AAudioBinderAdapter::closeStream(aaudio_handle_t streamHandle) {
+aaudio_result_t AAudioBinderAdapter::closeStream(const AAudioHandleInfo& streamHandleInfo) {
+ if (streamHandleInfo.getServiceLifetimeId() != mServiceLifetimeId) {
+ return AAUDIO_ERROR_DISCONNECTED;
+ }
aaudio_result_t result;
- Status status = mDelegate->closeStream(streamHandle, &result);
+ Status status = mDelegate->closeStream(streamHandleInfo.getHandle(), &result);
if (!status.isOk()) {
result = AAudioConvert_androidToAAudioResult(statusTFromBinderStatus(status));
}
return result;
}
-aaudio_result_t AAudioBinderAdapter::getStreamDescription(aaudio_handle_t streamHandle,
+aaudio_result_t AAudioBinderAdapter::getStreamDescription(const AAudioHandleInfo& streamHandleInfo,
AudioEndpointParcelable& endpointOut) {
+ if (streamHandleInfo.getServiceLifetimeId() != mServiceLifetimeId) {
+ return AAUDIO_ERROR_DISCONNECTED;
+ }
aaudio_result_t result;
Endpoint endpoint;
- Status status = mDelegate->getStreamDescription(streamHandle,
+ Status status = mDelegate->getStreamDescription(streamHandleInfo.getHandle(),
&endpoint,
&result);
if (!status.isOk()) {
@@ -67,68 +74,91 @@
return result;
}
-aaudio_result_t AAudioBinderAdapter::startStream(aaudio_handle_t streamHandle) {
+aaudio_result_t AAudioBinderAdapter::startStream(const AAudioHandleInfo& streamHandleInfo) {
+ if (streamHandleInfo.getServiceLifetimeId() != mServiceLifetimeId) {
+ return AAUDIO_ERROR_DISCONNECTED;
+ }
aaudio_result_t result;
- Status status = mDelegate->startStream(streamHandle, &result);
+ Status status = mDelegate->startStream(streamHandleInfo.getHandle(), &result);
if (!status.isOk()) {
result = AAudioConvert_androidToAAudioResult(statusTFromBinderStatus(status));
}
return result;
}
-aaudio_result_t AAudioBinderAdapter::pauseStream(aaudio_handle_t streamHandle) {
+aaudio_result_t AAudioBinderAdapter::pauseStream(const AAudioHandleInfo& streamHandleInfo) {
+ if (streamHandleInfo.getServiceLifetimeId() != mServiceLifetimeId) {
+ return AAUDIO_ERROR_DISCONNECTED;
+ }
aaudio_result_t result;
- Status status = mDelegate->pauseStream(streamHandle, &result);
+ Status status = mDelegate->pauseStream(streamHandleInfo.getHandle(), &result);
if (!status.isOk()) {
result = AAudioConvert_androidToAAudioResult(statusTFromBinderStatus(status));
}
return result;
}
-aaudio_result_t AAudioBinderAdapter::stopStream(aaudio_handle_t streamHandle) {
+aaudio_result_t AAudioBinderAdapter::stopStream(const AAudioHandleInfo& streamHandleInfo) {
+ if (streamHandleInfo.getServiceLifetimeId() != mServiceLifetimeId) {
+ return AAUDIO_ERROR_DISCONNECTED;
+ }
aaudio_result_t result;
- Status status = mDelegate->stopStream(streamHandle, &result);
+ Status status = mDelegate->stopStream(streamHandleInfo.getHandle(), &result);
if (!status.isOk()) {
result = AAudioConvert_androidToAAudioResult(statusTFromBinderStatus(status));
}
return result;
}
-aaudio_result_t AAudioBinderAdapter::flushStream(aaudio_handle_t streamHandle) {
+aaudio_result_t AAudioBinderAdapter::flushStream(const AAudioHandleInfo& streamHandleInfo) {
+ if (streamHandleInfo.getServiceLifetimeId() != mServiceLifetimeId) {
+ return AAUDIO_ERROR_DISCONNECTED;
+ }
aaudio_result_t result;
- Status status = mDelegate->flushStream(streamHandle, &result);
+ Status status = mDelegate->flushStream(streamHandleInfo.getHandle(), &result);
if (!status.isOk()) {
result = AAudioConvert_androidToAAudioResult(statusTFromBinderStatus(status));
}
return result;
}
-aaudio_result_t AAudioBinderAdapter::registerAudioThread(aaudio_handle_t streamHandle,
+aaudio_result_t AAudioBinderAdapter::registerAudioThread(const AAudioHandleInfo& streamHandleInfo,
pid_t clientThreadId,
int64_t periodNanoseconds) {
+ if (streamHandleInfo.getServiceLifetimeId() != mServiceLifetimeId) {
+ return AAUDIO_ERROR_DISCONNECTED;
+ }
aaudio_result_t result;
- Status status = mDelegate->registerAudioThread(streamHandle, clientThreadId, periodNanoseconds, &result);
+ Status status = mDelegate->registerAudioThread(
+ streamHandleInfo.getHandle(), clientThreadId, periodNanoseconds, &result);
if (!status.isOk()) {
result = AAudioConvert_androidToAAudioResult(statusTFromBinderStatus(status));
}
return result;
}
-aaudio_result_t AAudioBinderAdapter::unregisterAudioThread(aaudio_handle_t streamHandle,
+aaudio_result_t AAudioBinderAdapter::unregisterAudioThread(const AAudioHandleInfo& streamHandleInfo,
pid_t clientThreadId) {
+ if (streamHandleInfo.getServiceLifetimeId() != mServiceLifetimeId) {
+ return AAUDIO_ERROR_DISCONNECTED;
+ }
aaudio_result_t result;
- Status status = mDelegate->unregisterAudioThread(streamHandle, clientThreadId, &result);
+ Status status = mDelegate->unregisterAudioThread(
+ streamHandleInfo.getHandle(), clientThreadId, &result);
if (!status.isOk()) {
result = AAudioConvert_androidToAAudioResult(statusTFromBinderStatus(status));
}
return result;
}
-aaudio_result_t AAudioBinderAdapter::exitStandby(aaudio_handle_t streamHandle,
+aaudio_result_t AAudioBinderAdapter::exitStandby(const AAudioHandleInfo& streamHandleInfo,
AudioEndpointParcelable &endpointOut) {
+ if (streamHandleInfo.getServiceLifetimeId() != mServiceLifetimeId) {
+ return AAUDIO_ERROR_DISCONNECTED;
+ }
aaudio_result_t result;
Endpoint endpoint;
- Status status = mDelegate->exitStandby(streamHandle, &endpoint, &result);
+ Status status = mDelegate->exitStandby(streamHandleInfo.getHandle(), &endpoint, &result);
if (!status.isOk()) {
result = AAudioConvert_androidToAAudioResult(statusTFromBinderStatus(status));
}
diff --git a/media/libaaudio/src/binding/AAudioBinderAdapter.h b/media/libaaudio/src/binding/AAudioBinderAdapter.h
index d170783..301150f 100644
--- a/media/libaaudio/src/binding/AAudioBinderAdapter.h
+++ b/media/libaaudio/src/binding/AAudioBinderAdapter.h
@@ -30,38 +30,40 @@
*/
class AAudioBinderAdapter : public AAudioServiceInterface {
public:
- explicit AAudioBinderAdapter(IAAudioService* delegate);
+ AAudioBinderAdapter(IAAudioService* delegate, int32_t serviceLifetimeId);
void registerClient(const android::sp<IAAudioClient>& client) override;
- aaudio_handle_t openStream(const AAudioStreamRequest& request,
- AAudioStreamConfiguration& configuration) override;
+ AAudioHandleInfo openStream(const AAudioStreamRequest& request,
+ AAudioStreamConfiguration& configuration) 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& endpoint) 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,
+ 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 exitStandby(aaudio_handle_t streamHandle,
+ aaudio_result_t exitStandby(const AAudioHandleInfo& streamHandleInfo,
AudioEndpointParcelable &parcelable) override;
private:
IAAudioService* const mDelegate;
+ // A unique id to recognize the service that the adapter connected to.
+ const int32_t mServiceLifetimeId;
};
} // namespace aaudio
diff --git a/media/libaaudio/src/binding/AAudioBinderClient.cpp b/media/libaaudio/src/binding/AAudioBinderClient.cpp
index 8e5facc..5f34a75 100644
--- a/media/libaaudio/src/binding/AAudioBinderClient.cpp
+++ b/media/libaaudio/src/binding/AAudioBinderClient.cpp
@@ -90,7 +90,8 @@
ALOGE("%s() - linkToDeath() returned %d", __func__, status);
}
aaudioService = interface_cast<IAAudioService>(binder);
- mAdapter = std::make_shared<Adapter>(aaudioService, mAAudioClient);
+ mAdapter = std::make_shared<Adapter>(
+ aaudioService, mAAudioClient, mAAudioClient->getServiceLifetimeId());
needToRegister = true;
// Make sure callbacks can be received by mAAudioClient
ProcessState::self()->startThreadPool();
@@ -115,97 +116,101 @@
/**
* @param request info needed to create the stream
* @param configuration contains information about the created stream
-* @return handle to the stream or a negative error
+* @return an object for aaudio handle information, which includes the connected
+* aaudio service lifetime id to recognize the connected aaudio service
+* and aaudio handle to recognize the stream. If an error occurs, the
+* aaudio handle will be set as the negative error.
*/
-aaudio_handle_t AAudioBinderClient::openStream(const AAudioStreamRequest &request,
- AAudioStreamConfiguration &configuration) {
- aaudio_handle_t stream;
+AAudioHandleInfo AAudioBinderClient::openStream(const AAudioStreamRequest &request,
+ AAudioStreamConfiguration &configuration) {
for (int i = 0; i < 2; i++) {
std::shared_ptr<AAudioServiceInterface> service = getAAudioService();
- if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE;
+ if (service.get() == nullptr) {
+ return {};
+ }
- stream = service->openStream(request, configuration);
+ AAudioHandleInfo handleInfo = service->openStream(request, configuration);
- if (stream == AAUDIO_ERROR_NO_SERVICE) {
+ if (handleInfo.getHandle() == AAUDIO_ERROR_NO_SERVICE) {
ALOGE("openStream lost connection to AAudioService.");
dropAAudioService(); // force a reconnect
} else {
- break;
+ return handleInfo;
}
}
- return stream;
+ return {};
}
-aaudio_result_t AAudioBinderClient::closeStream(aaudio_handle_t streamHandle) {
+aaudio_result_t AAudioBinderClient::closeStream(const AAudioHandleInfo& streamHandleInfo) {
std::shared_ptr<AAudioServiceInterface> service = getAAudioService();
if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE;
- return service->closeStream(streamHandle);
+ return service->closeStream(streamHandleInfo);
}
/* Get an immutable description of the in-memory queues
* used to communicate with the underlying HAL or Service.
*/
-aaudio_result_t AAudioBinderClient::getStreamDescription(aaudio_handle_t streamHandle,
+aaudio_result_t AAudioBinderClient::getStreamDescription(const AAudioHandleInfo& streamHandleInfo,
AudioEndpointParcelable& endpointOut) {
std::shared_ptr<AAudioServiceInterface> service = getAAudioService();
if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE;
- return service->getStreamDescription(streamHandle, endpointOut);
+ return service->getStreamDescription(streamHandleInfo, endpointOut);
}
-aaudio_result_t AAudioBinderClient::startStream(aaudio_handle_t streamHandle) {
+aaudio_result_t AAudioBinderClient::startStream(const AAudioHandleInfo& streamHandleInfo) {
std::shared_ptr<AAudioServiceInterface> service = getAAudioService();
if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE;
- return service->startStream(streamHandle);
+ return service->startStream(streamHandleInfo);
}
-aaudio_result_t AAudioBinderClient::pauseStream(aaudio_handle_t streamHandle) {
+aaudio_result_t AAudioBinderClient::pauseStream(const AAudioHandleInfo& streamHandleInfo) {
std::shared_ptr<AAudioServiceInterface> service = getAAudioService();
if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE;
- return service->pauseStream(streamHandle);
+ return service->pauseStream(streamHandleInfo);
}
-aaudio_result_t AAudioBinderClient::stopStream(aaudio_handle_t streamHandle) {
+aaudio_result_t AAudioBinderClient::stopStream(const AAudioHandleInfo& streamHandleInfo) {
std::shared_ptr<AAudioServiceInterface> service = getAAudioService();
if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE;
- return service->stopStream(streamHandle);
+ return service->stopStream(streamHandleInfo);
}
-aaudio_result_t AAudioBinderClient::flushStream(aaudio_handle_t streamHandle) {
+aaudio_result_t AAudioBinderClient::flushStream(const AAudioHandleInfo& streamHandleInfo) {
std::shared_ptr<AAudioServiceInterface> service = getAAudioService();
if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE;
- return service->flushStream(streamHandle);
+ return service->flushStream(streamHandleInfo);
}
/**
* Manage the specified thread as a low latency audio thread.
*/
-aaudio_result_t AAudioBinderClient::registerAudioThread(aaudio_handle_t streamHandle,
+aaudio_result_t AAudioBinderClient::registerAudioThread(const AAudioHandleInfo& streamHandleInfo,
pid_t clientThreadId,
int64_t periodNanoseconds) {
std::shared_ptr<AAudioServiceInterface> service = getAAudioService();
if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE;
- return service->registerAudioThread(streamHandle, clientThreadId, periodNanoseconds);
+ return service->registerAudioThread(streamHandleInfo, clientThreadId, periodNanoseconds);
}
-aaudio_result_t AAudioBinderClient::unregisterAudioThread(aaudio_handle_t streamHandle,
+aaudio_result_t AAudioBinderClient::unregisterAudioThread(const AAudioHandleInfo& streamHandleInfo,
pid_t clientThreadId) {
std::shared_ptr<AAudioServiceInterface> service = getAAudioService();
if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE;
- return service->unregisterAudioThread(streamHandle, clientThreadId);
+ return service->unregisterAudioThread(streamHandleInfo, clientThreadId);
}
-aaudio_result_t AAudioBinderClient::exitStandby(aaudio_handle_t streamHandle,
+aaudio_result_t AAudioBinderClient::exitStandby(const AAudioHandleInfo& streamHandleInfo,
AudioEndpointParcelable &endpointOut) {
std::shared_ptr<AAudioServiceInterface> service = getAAudioService();
if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE;
- return service->exitStandby(streamHandle, endpointOut);
+ return service->exitStandby(streamHandleInfo, endpointOut);
}
diff --git a/media/libaaudio/src/binding/AAudioBinderClient.h b/media/libaaudio/src/binding/AAudioBinderClient.h
index 0968f4c..8faf6e8 100644
--- a/media/libaaudio/src/binding/AAudioBinderClient.h
+++ b/media/libaaudio/src/binding/AAudioBinderClient.h
@@ -17,6 +17,8 @@
#ifndef ANDROID_AAUDIO_AAUDIO_BINDER_CLIENT_H
#define ANDROID_AAUDIO_AAUDIO_BINDER_CLIENT_H
+#include <mutex>
+
#include <utils/RefBase.h>
#include <utils/Singleton.h>
@@ -52,63 +54,66 @@
/**
* @param request info needed to create the stream
* @param configuration contains resulting information about the created stream
- * @return handle to the stream or a negative error
+ * @return an object for aaudio handle information, which includes the connected
+ * aaudio service lifetime id to recognize the connected aaudio service
+ * and aaudio handle to recognize the stream. If an error occurs, the
+ * aaudio handle will be set as the negative error.
*/
- 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;
/* Get an immutable description of the in-memory queues
* used to communicate with the underlying HAL or Service.
*/
- aaudio_result_t getStreamDescription(aaudio_handle_t streamHandle,
+ aaudio_result_t getStreamDescription(const AAudioHandleInfo& streamHandleInfo,
AudioEndpointParcelable &endpointOut) override;
/**
* Start the flow of data.
* This is asynchronous. When complete, the service will send a STARTED event.
*/
- aaudio_result_t startStream(aaudio_handle_t streamHandle) override;
+ aaudio_result_t startStream(const AAudioHandleInfo& streamHandleInfo) override;
/**
* Stop the flow of data such that start() can resume without loss of data.
* This is asynchronous. When complete, the service will send a PAUSED event.
*/
- 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;
/**
* Discard any data held by the underlying HAL or Service.
* This is asynchronous. When complete, the service will send a FLUSHED event.
*/
- aaudio_result_t flushStream(aaudio_handle_t streamHandle) override;
+ aaudio_result_t flushStream(const AAudioHandleInfo& streamHandleInfo) override;
/**
* Manage the specified thread as a low latency audio thread.
* TODO Consider passing this information as part of the startStream() call.
*/
- aaudio_result_t registerAudioThread(aaudio_handle_t streamHandle,
- pid_t clientThreadId,
- int64_t periodNanoseconds) override;
+ aaudio_result_t registerAudioThread(const AAudioHandleInfo& streamHandleInfo,
+ pid_t clientThreadId,
+ int64_t periodNanoseconds) override;
- aaudio_result_t unregisterAudioThread(aaudio_handle_t streamHandle,
- pid_t clientThreadId) override;
+ aaudio_result_t unregisterAudioThread(const AAudioHandleInfo& streamHandleInfo,
+ pid_t clientThreadId) override;
- aaudio_result_t startClient(aaudio_handle_t streamHandle __unused,
+ aaudio_result_t startClient(const AAudioHandleInfo& streamHandleInfo __unused,
const android::AudioClient& client __unused,
const audio_attributes_t *attr __unused,
audio_port_handle_t *clientHandle __unused) override {
return AAUDIO_ERROR_UNAVAILABLE;
}
- aaudio_result_t stopClient(aaudio_handle_t streamHandle __unused,
+ aaudio_result_t stopClient(const AAudioHandleInfo& streamHandleInfo __unused,
audio_port_handle_t clientHandle __unused) override {
return AAUDIO_ERROR_UNAVAILABLE;
}
- aaudio_result_t exitStandby(aaudio_handle_t streamHandle,
+ aaudio_result_t exitStandby(const AAudioHandleInfo& streamHandleInfo,
AudioEndpointParcelable &endpointOut) override;
void onStreamChange(aaudio_handle_t /*handle*/, int32_t /*opcode*/, int32_t /*value*/) {
@@ -117,6 +122,10 @@
ALOGW("onStreamChange called!");
}
+ int32_t getServiceLifetimeId() const {
+ return mAAudioClient->getServiceLifetimeId();
+ }
+
class AAudioClient : public android::IBinder::DeathRecipient, public BnAAudioClient {
public:
explicit AAudioClient(const android::wp<AAudioBinderClient>& aaudioBinderClient)
@@ -125,6 +134,7 @@
// implement DeathRecipient
virtual void binderDied(const android::wp<android::IBinder>& who __unused) {
+ mServiceLifetimeId++;
android::sp<AAudioBinderClient> client = mBinderClient.promote();
if (client.get() != nullptr) {
client->dropAAudioService();
@@ -141,8 +151,13 @@
}
return android::binder::Status::ok();
}
+
+ int32_t getServiceLifetimeId() const {
+ return mServiceLifetimeId.load();
+ }
private:
android::wp<AAudioBinderClient> mBinderClient;
+ std::atomic_int mServiceLifetimeId{0};
};
// This adapter is used to convert the binder interface (delegate) to the AudioServiceInterface
@@ -153,8 +168,9 @@
class Adapter : public AAudioBinderAdapter {
public:
Adapter(const android::sp<IAAudioService>& delegate,
- android::sp<AAudioClient> aaudioClient)
- : AAudioBinderAdapter(delegate.get()),
+ android::sp<AAudioClient> aaudioClient,
+ int32_t serviceLifetimeId)
+ : AAudioBinderAdapter(delegate.get(), serviceLifetimeId),
mDelegate(delegate),
mAAudioClient(std::move(aaudioClient)) {}
@@ -165,7 +181,7 @@
}
// This should never be called (call is rejected at the AudioBinderClient level).
- aaudio_result_t startClient(aaudio_handle_t streamHandle __unused,
+ aaudio_result_t startClient(const AAudioHandleInfo& streamHandle __unused,
const android::AudioClient& client __unused,
const audio_attributes_t* attr __unused,
audio_port_handle_t* clientHandle __unused) override {
@@ -174,7 +190,7 @@
}
// This should never be called (call is rejected at the AudioBinderClient level).
- aaudio_result_t stopClient(aaudio_handle_t streamHandle __unused,
+ aaudio_result_t stopClient(const AAudioHandleInfo& streamHandle __unused,
audio_port_handle_t clientHandle __unused) override {
LOG_ALWAYS_FATAL("Shouldn't get here");
return AAUDIO_ERROR_UNAVAILABLE;
diff --git a/media/libaaudio/src/binding/AAudioServiceDefinitions.h b/media/libaaudio/src/binding/AAudioServiceDefinitions.h
index 8a2303c..7b8978f 100644
--- a/media/libaaudio/src/binding/AAudioServiceDefinitions.h
+++ b/media/libaaudio/src/binding/AAudioServiceDefinitions.h
@@ -85,6 +85,23 @@
RingBufferDescriptor dataQueueDescriptor; // playback or capture
} EndpointDescriptor;
+static constexpr int32_t AAUDIO_SERVICE_LIFETIME_ID_INVALID = -1;
+
+class AAudioHandleInfo {
+public:
+ AAudioHandleInfo()
+ : AAudioHandleInfo(AAUDIO_SERVICE_LIFETIME_ID_INVALID, AAUDIO_HANDLE_INVALID) {}
+ AAudioHandleInfo(int32_t serviceLifetimeId, aaudio_handle_t handle)
+ : mServiceLifetimeId(serviceLifetimeId), mHandle(handle) {}
+
+ int32_t getServiceLifetimeId() const { return mServiceLifetimeId; }
+ aaudio_handle_t getHandle() const { return mHandle; }
+
+private:
+ int32_t mServiceLifetimeId;
+ aaudio_handle_t mHandle;
+};
+
} // namespace aaudio
#endif //BINDING_AAUDIOSERVICEDEFINITIONS_H
diff --git a/media/libaaudio/src/binding/AAudioServiceInterface.h b/media/libaaudio/src/binding/AAudioServiceInterface.h
index e901767..79f498b 100644
--- a/media/libaaudio/src/binding/AAudioServiceInterface.h
+++ b/media/libaaudio/src/binding/AAudioServiceInterface.h
@@ -45,55 +45,58 @@
/**
* @param request info needed to create the stream
* @param configuration contains information about the created stream
- * @return handle to the stream or a negative error
+ * @return an object for aaudio handle information, which includes the connected
+ * aaudio service lifetime id to recognize the connected aaudio service
+ * and aaudio handle to recognize the stream. If an error occurs, the
+ * aaudio handle will be set as the negative error.
*/
- virtual aaudio_handle_t openStream(const AAudioStreamRequest &request,
- AAudioStreamConfiguration &configuration) = 0;
+ virtual AAudioHandleInfo openStream(const AAudioStreamRequest &request,
+ AAudioStreamConfiguration &configuration) = 0;
- virtual aaudio_result_t closeStream(aaudio_handle_t streamHandle) = 0;
+ virtual aaudio_result_t closeStream(const AAudioHandleInfo& streamHandleInfo) = 0;
/* Get an immutable description of the in-memory queues
* used to communicate with the underlying HAL or Service.
*/
- virtual aaudio_result_t getStreamDescription(aaudio_handle_t streamHandle,
+ virtual aaudio_result_t getStreamDescription(const AAudioHandleInfo& streamHandleInfo,
AudioEndpointParcelable &parcelable) = 0;
/**
* Start the flow of data.
*/
- virtual aaudio_result_t startStream(aaudio_handle_t streamHandle) = 0;
+ virtual aaudio_result_t startStream(const AAudioHandleInfo& streamHandleInfo) = 0;
/**
* Stop the flow of data such that start() can resume without loss of data.
*/
- virtual aaudio_result_t pauseStream(aaudio_handle_t streamHandle) = 0;
+ virtual aaudio_result_t pauseStream(const AAudioHandleInfo& streamHandleInfo) = 0;
/**
- * Stop the flow of data after data currently inthe buffer has played.
+ * Stop the flow of data after data currently in the buffer has played.
*/
- virtual aaudio_result_t stopStream(aaudio_handle_t streamHandle) = 0;
+ virtual aaudio_result_t stopStream(const AAudioHandleInfo& streamHandleInfo) = 0;
/**
* Discard any data held by the underlying HAL or Service.
*/
- virtual aaudio_result_t flushStream(aaudio_handle_t streamHandle) = 0;
+ virtual aaudio_result_t flushStream(const AAudioHandleInfo& streamHandleInfo) = 0;
/**
* Manage the specified thread as a low latency audio thread.
*/
- virtual aaudio_result_t registerAudioThread(aaudio_handle_t streamHandle,
+ virtual aaudio_result_t registerAudioThread(const AAudioHandleInfo& streamHandleInfo,
pid_t clientThreadId,
int64_t periodNanoseconds) = 0;
- virtual aaudio_result_t unregisterAudioThread(aaudio_handle_t streamHandle,
+ virtual aaudio_result_t unregisterAudioThread(const AAudioHandleInfo& streamHandleInfo,
pid_t clientThreadId) = 0;
- virtual aaudio_result_t startClient(aaudio_handle_t streamHandle,
+ virtual aaudio_result_t startClient(const AAudioHandleInfo& streamHandleInfo,
const android::AudioClient& client,
const audio_attributes_t *attr,
audio_port_handle_t *clientHandle) = 0;
- virtual aaudio_result_t stopClient(aaudio_handle_t streamHandle,
+ virtual aaudio_result_t stopClient(const AAudioHandleInfo& streamHandleInfo,
audio_port_handle_t clientHandle) = 0;
/**
@@ -103,7 +106,7 @@
* @param parcelable contains new data queue information
* @return the result of the execution
*/
- virtual aaudio_result_t exitStandby(aaudio_handle_t streamHandle,
+ virtual aaudio_result_t exitStandby(const AAudioHandleInfo& streamHandleInfo,
AudioEndpointParcelable &parcelable) = 0;
};
diff --git a/media/libaaudio/src/client/AudioStreamInternal.cpp b/media/libaaudio/src/client/AudioStreamInternal.cpp
index 525ebb4..84c715f 100644
--- a/media/libaaudio/src/client/AudioStreamInternal.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternal.cpp
@@ -33,6 +33,7 @@
#include <utils/Trace.h>
#include "AudioEndpointParcelable.h"
+#include "binding/AAudioBinderClient.h"
#include "binding/AAudioStreamRequest.h"
#include "binding/AAudioStreamConfiguration.h"
#include "binding/AAudioServiceMessage.h"
@@ -65,13 +66,13 @@
AudioStreamInternal::AudioStreamInternal(AAudioServiceInterface &serviceInterface, bool inService)
: AudioStream()
, mClockModel()
- , mServiceStreamHandle(AAUDIO_HANDLE_INVALID)
, mInService(inService)
, mServiceInterface(serviceInterface)
, mAtomicInternalTimestamp()
, mWakeupDelayNanos(AAudioProperty_getWakeupDelayMicros() * AAUDIO_NANOS_PER_MICROSECOND)
, mMinimumSleepNanos(AAudioProperty_getMinimumSleepMicros() * AAUDIO_NANOS_PER_MICROSECOND)
{
+
}
AudioStreamInternal::~AudioStreamInternal() {
@@ -137,8 +138,8 @@
mDeviceChannelCount = getSamplesPerFrame(); // Assume it will be the same. Update if not.
- mServiceStreamHandle = mServiceInterface.openStream(request, configurationOutput);
- if (mServiceStreamHandle < 0
+ mServiceStreamHandleInfo = mServiceInterface.openStream(request, configurationOutput);
+ if (getServiceHandle() < 0
&& (request.getConfiguration().getSamplesPerFrame() == 1
|| request.getConfiguration().getChannelMask() == AAUDIO_CHANNEL_MONO)
&& getDirection() == AAUDIO_DIRECTION_OUTPUT
@@ -147,12 +148,12 @@
// Only do this in the client. Otherwise we end up with a mono mixer in the service
// that writes to a stereo MMAP stream.
ALOGD("%s() - openStream() returned %d, try switching from MONO to STEREO",
- __func__, mServiceStreamHandle);
+ __func__, getServiceHandle());
request.getConfiguration().setChannelMask(AAUDIO_CHANNEL_STEREO);
- mServiceStreamHandle = mServiceInterface.openStream(request, configurationOutput);
+ mServiceStreamHandleInfo = mServiceInterface.openStream(request, configurationOutput);
}
- if (mServiceStreamHandle < 0) {
- return mServiceStreamHandle;
+ if (getServiceHandle() < 0) {
+ return getServiceHandle();
}
// This must match the key generated in oboeservice/AAudioServiceStreamBase.cpp
@@ -160,7 +161,7 @@
if (!mInService) {
// No need to log if it is from service side.
mMetricsId = std::string(AMEDIAMETRICS_KEY_PREFIX_AUDIO_STREAM)
- + std::to_string(mServiceStreamHandle);
+ + std::to_string(getServiceHandle());
}
android::mediametrics::LogItem(mMetricsId)
@@ -200,7 +201,7 @@
setHardwareSampleRate(configurationOutput.getHardwareSampleRate());
setHardwareFormat(configurationOutput.getHardwareFormat());
- result = mServiceInterface.getStreamDescription(mServiceStreamHandle, mEndPointParcelable);
+ result = mServiceInterface.getStreamDescription(mServiceStreamHandleInfo, mEndPointParcelable);
if (result != AAUDIO_OK) {
goto error;
}
@@ -321,8 +322,8 @@
// This must be called under mStreamLock.
aaudio_result_t AudioStreamInternal::release_l() {
aaudio_result_t result = AAUDIO_OK;
- ALOGD("%s(): mServiceStreamHandle = 0x%08X", __func__, mServiceStreamHandle);
- if (mServiceStreamHandle != AAUDIO_HANDLE_INVALID) {
+ ALOGD("%s(): mServiceStreamHandle = 0x%08X", __func__, getServiceHandle());
+ if (getServiceHandle() != AAUDIO_HANDLE_INVALID) {
// Don't release a stream while it is running. Stop it first.
// If DISCONNECTED then we should still try to stop in case the
// error callback is still running.
@@ -333,10 +334,10 @@
logReleaseBufferState();
setState(AAUDIO_STREAM_STATE_CLOSING);
- aaudio_handle_t serviceStreamHandle = mServiceStreamHandle;
- mServiceStreamHandle = AAUDIO_HANDLE_INVALID;
+ auto serviceStreamHandleInfo = mServiceStreamHandleInfo;
+ mServiceStreamHandleInfo = AAudioHandleInfo();
- mServiceInterface.closeStream(serviceStreamHandle);
+ mServiceInterface.closeStream(serviceStreamHandleInfo);
mCallbackBuffer.reset();
// Update local frame counters so we can query them after releasing the endpoint.
@@ -378,7 +379,7 @@
mAudioEndpoint->read(buffer, getBufferCapacity());
mEndPointParcelable.closeDataFileDescriptor();
aaudio_result_t result = mServiceInterface.exitStandby(
- mServiceStreamHandle, endpointParcelable);
+ mServiceStreamHandleInfo, endpointParcelable);
if (result != AAUDIO_OK) {
ALOGE("Failed to exit standby, error=%d", result);
goto exit;
@@ -434,7 +435,7 @@
aaudio_result_t AudioStreamInternal::requestStart_l()
{
int64_t startTime;
- if (mServiceStreamHandle == AAUDIO_HANDLE_INVALID) {
+ if (getServiceHandle() == AAUDIO_HANDLE_INVALID) {
ALOGD("requestStart() mServiceStreamHandle invalid");
return AAUDIO_ERROR_INVALID_STATE;
}
@@ -455,12 +456,12 @@
prepareBuffersForStart(); // tell subclasses to get ready
- aaudio_result_t result = mServiceInterface.startStream(mServiceStreamHandle);
+ aaudio_result_t result = mServiceInterface.startStream(mServiceStreamHandleInfo);
if (result == AAUDIO_ERROR_STANDBY) {
// The stream is at standby mode. Need to exit standby before starting the stream.
result = exitStandby_l();
if (result == AAUDIO_OK) {
- result = mServiceInterface.startStream(mServiceStreamHandle);
+ result = mServiceInterface.startStream(mServiceStreamHandleInfo);
}
}
if (result != AAUDIO_OK) {
@@ -539,9 +540,9 @@
return AAUDIO_OK;
}
- if (mServiceStreamHandle == AAUDIO_HANDLE_INVALID) {
+ if (getServiceHandle() == AAUDIO_HANDLE_INVALID) {
ALOGW("%s() mServiceStreamHandle invalid = 0x%08X",
- __func__, mServiceStreamHandle);
+ __func__, getServiceHandle());
return AAUDIO_ERROR_INVALID_STATE;
}
@@ -549,7 +550,7 @@
setState(AAUDIO_STREAM_STATE_STOPPING);
mAtomicInternalTimestamp.clear();
- result = mServiceInterface.stopStream(mServiceStreamHandle);
+ result = mServiceInterface.stopStream(mServiceStreamHandleInfo);
if (result == AAUDIO_ERROR_INVALID_HANDLE) {
ALOGD("%s() INVALID_HANDLE, stream was probably stolen", __func__);
result = AAUDIO_OK;
@@ -558,31 +559,31 @@
}
aaudio_result_t AudioStreamInternal::registerThread() {
- if (mServiceStreamHandle == AAUDIO_HANDLE_INVALID) {
+ if (getServiceHandle() == AAUDIO_HANDLE_INVALID) {
ALOGW("%s() mServiceStreamHandle invalid", __func__);
return AAUDIO_ERROR_INVALID_STATE;
}
- return mServiceInterface.registerAudioThread(mServiceStreamHandle,
- gettid(),
- getPeriodNanoseconds());
+ return mServiceInterface.registerAudioThread(mServiceStreamHandleInfo,
+ gettid(),
+ getPeriodNanoseconds());
}
aaudio_result_t AudioStreamInternal::unregisterThread() {
- if (mServiceStreamHandle == AAUDIO_HANDLE_INVALID) {
+ if (getServiceHandle() == AAUDIO_HANDLE_INVALID) {
ALOGW("%s() mServiceStreamHandle invalid", __func__);
return AAUDIO_ERROR_INVALID_STATE;
}
- return mServiceInterface.unregisterAudioThread(mServiceStreamHandle, gettid());
+ return mServiceInterface.unregisterAudioThread(mServiceStreamHandleInfo, gettid());
}
aaudio_result_t AudioStreamInternal::startClient(const android::AudioClient& client,
const audio_attributes_t *attr,
audio_port_handle_t *portHandle) {
ALOGV("%s() called", __func__);
- if (mServiceStreamHandle == AAUDIO_HANDLE_INVALID) {
+ if (getServiceHandle() == AAUDIO_HANDLE_INVALID) {
return AAUDIO_ERROR_INVALID_STATE;
}
- aaudio_result_t result = mServiceInterface.startClient(mServiceStreamHandle,
+ aaudio_result_t result = mServiceInterface.startClient(mServiceStreamHandleInfo,
client, attr, portHandle);
ALOGV("%s(%d) returning %d", __func__, *portHandle, result);
return result;
@@ -590,10 +591,10 @@
aaudio_result_t AudioStreamInternal::stopClient(audio_port_handle_t portHandle) {
ALOGV("%s(%d) called", __func__, portHandle);
- if (mServiceStreamHandle == AAUDIO_HANDLE_INVALID) {
+ if (getServiceHandle() == AAUDIO_HANDLE_INVALID) {
return AAUDIO_ERROR_INVALID_STATE;
}
- aaudio_result_t result = mServiceInterface.stopClient(mServiceStreamHandle, portHandle);
+ aaudio_result_t result = mServiceInterface.stopClient(mServiceStreamHandleInfo, portHandle);
ALOGV("%s(%d) returning %d", __func__, portHandle, result);
return result;
}
@@ -770,6 +771,22 @@
aaudio_result_t AudioStreamInternal::processData(void *buffer, int32_t numFrames,
int64_t timeoutNanoseconds)
{
+ if (isDisconnected()) {
+ return AAUDIO_ERROR_DISCONNECTED;
+ }
+ if (!mInService &&
+ AAudioBinderClient::getInstance().getServiceLifetimeId() != getServiceLifetimeId()) {
+ // The service lifetime id will be changed whenever the binder died. In that case, if
+ // the service lifetime id from AAudioBinderClient is different from the cached one,
+ // returns AAUDIO_ERROR_DISCONNECTED.
+ // Note that only compare the service lifetime id if it is not in service as the streams
+ // in service will all be gone when aaudio service dies.
+ mClockModel.stop(AudioClock::getNanoseconds());
+ // Set the stream as disconnected as the service lifetime id will only change when
+ // the binder dies.
+ setDisconnected();
+ return AAUDIO_ERROR_DISCONNECTED;
+ }
const char * traceName = "aaProc";
const char * fifoName = "aaRdy";
ATRACE_BEGIN(traceName);
diff --git a/media/libaaudio/src/client/AudioStreamInternal.h b/media/libaaudio/src/client/AudioStreamInternal.h
index 4ea61d2..9c06121 100644
--- a/media/libaaudio/src/client/AudioStreamInternal.h
+++ b/media/libaaudio/src/client/AudioStreamInternal.h
@@ -83,7 +83,11 @@
aaudio_result_t stopClient(audio_port_handle_t clientHandle);
aaudio_handle_t getServiceHandle() const {
- return mServiceStreamHandle;
+ return mServiceStreamHandleInfo.getHandle();
+ }
+
+ int32_t getServiceLifetimeId() const {
+ return mServiceStreamHandleInfo.getServiceLifetimeId();
}
protected:
@@ -148,7 +152,8 @@
std::unique_ptr<AudioEndpoint> mAudioEndpoint; // source for reads or sink for writes
- aaudio_handle_t mServiceStreamHandle; // opaque handle returned from service
+ // opaque handle returned from service
+ AAudioHandleInfo mServiceStreamHandleInfo;
int32_t mXRunCount = 0; // how many underrun events?
diff --git a/media/libaaudio/src/client/AudioStreamInternalPlay.cpp b/media/libaaudio/src/client/AudioStreamInternalPlay.cpp
index 7c7a969..89dd8ff 100644
--- a/media/libaaudio/src/client/AudioStreamInternalPlay.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternalPlay.cpp
@@ -74,7 +74,7 @@
if (result != AAUDIO_OK) {
return result;
}
- if (mServiceStreamHandle == AAUDIO_HANDLE_INVALID) {
+ if (getServiceHandle() == AAUDIO_HANDLE_INVALID) {
ALOGW("%s() mServiceStreamHandle invalid", __func__);
return AAUDIO_ERROR_INVALID_STATE;
}
@@ -82,17 +82,17 @@
mClockModel.stop(AudioClock::getNanoseconds());
setState(AAUDIO_STREAM_STATE_PAUSING);
mAtomicInternalTimestamp.clear();
- return mServiceInterface.pauseStream(mServiceStreamHandle);
+ return mServiceInterface.pauseStream(mServiceStreamHandleInfo);
}
aaudio_result_t AudioStreamInternalPlay::requestFlush_l() {
- if (mServiceStreamHandle == AAUDIO_HANDLE_INVALID) {
+ if (getServiceHandle() == AAUDIO_HANDLE_INVALID) {
ALOGW("%s() mServiceStreamHandle invalid", __func__);
return AAUDIO_ERROR_INVALID_STATE;
}
setState(AAUDIO_STREAM_STATE_FLUSHING);
- return mServiceInterface.flushStream(mServiceStreamHandle);
+ return mServiceInterface.flushStream(mServiceStreamHandleInfo);
}
void AudioStreamInternalPlay::prepareBuffersForStart() {
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);
}