Convert AAudioService to AIDL
This change removes all hand-written binder code associated with
parceling of AAudio types and IAAudioService interface.
The existing types defined in the 'binding' directory have not been
replaced by their AIDL counterparts, but rather were made convertible
to/from them (in lieu of them being parcelables themselves).
The reasons are:
- Some of those types offer additional functionality rather than
simply being data containers / serializers. For example, the
SharedMemoryParcelable type supports mmaping a memory region.
- Reduce impact on existing code, which relies on the interface
offered by those type, which is different than the interface offered
by their AIDL counterparts.
The conversion between those types and their parcelable counterparts
is handled at the edge of the client (inside AAudioBinderAdapter) and
server (inside AAudioService) code.
Future changes may gradually get rid of the duality by retiring the
data types in the 'binding' directory, inlining some of the features
they are offering (such as accessor methods) and replacing others with
utility functions, operation on the parcelables directly.
Bug: 160253486
Test: Manual testing using OboeTester
Ran atest CtsNativeMediaAAudioTestCases
Ran atest test_aaudio_marshalling
Change-Id: I6eed19246a472dc31c1e2d6d2112d7562cf8940c
diff --git a/media/libaaudio/src/Android.bp b/media/libaaudio/src/Android.bp
index 23e9857..328ceda 100644
--- a/media/libaaudio/src/Android.bp
+++ b/media/libaaudio/src/Android.bp
@@ -119,7 +119,6 @@
"binding/AAudioBinderClient.cpp",
"binding/AAudioStreamRequest.cpp",
"binding/AAudioStreamConfiguration.cpp",
- "binding/IAAudioService.cpp",
"binding/RingBufferParcelable.cpp",
"binding/SharedMemoryParcelable.cpp",
"binding/SharedRegionParcelable.cpp",
@@ -145,6 +144,27 @@
unstable: true,
local_include_dir: "binding/aidl",
srcs: [
+ "binding/aidl/aaudio/Endpoint.aidl",
+ "binding/aidl/aaudio/RingBuffer.aidl",
+ "binding/aidl/aaudio/SharedRegion.aidl",
+ "binding/aidl/aaudio/StreamParameters.aidl",
+ "binding/aidl/aaudio/StreamRequest.aidl",
"binding/aidl/aaudio/IAAudioClient.aidl",
+ "binding/aidl/aaudio/IAAudioService.aidl",
],
+ imports: [
+ "audio_common-aidl",
+ "shared-file-region-aidl",
+ ],
+ backend:
+ {
+ cpp: {
+ enabled: true,
+ },
+ java: {
+ // TODO: need to have audio_common-aidl available in Java to enable
+ // this.
+ enabled: false,
+ },
+ },
}
diff --git a/media/libaaudio/src/binding/AAudioBinderAdapter.cpp b/media/libaaudio/src/binding/AAudioBinderAdapter.cpp
index 518c2c0..2b2fe6d 100644
--- a/media/libaaudio/src/binding/AAudioBinderAdapter.cpp
+++ b/media/libaaudio/src/binding/AAudioBinderAdapter.cpp
@@ -15,55 +15,111 @@
*/
#include <binding/AAudioBinderAdapter.h>
+#include <utility/AAudioUtilities.h>
namespace aaudio {
-AAudioBinderAdapter::AAudioBinderAdapter(android::IAAudioService *delegate)
+using android::binder::Status;
+
+AAudioBinderAdapter::AAudioBinderAdapter(IAAudioService* delegate)
: mDelegate(delegate) {}
-void AAudioBinderAdapter::registerClient(const android::sp<aaudio::IAAudioClient> &client) {
+void AAudioBinderAdapter::registerClient(const android::sp<IAAudioClient>& client) {
mDelegate->registerClient(client);
}
-aaudio_handle_t AAudioBinderAdapter::openStream(const AAudioStreamRequest &request,
- AAudioStreamConfiguration &configuration) {
- return mDelegate->openStream(request, configuration);
+aaudio_handle_t AAudioBinderAdapter::openStream(const AAudioStreamRequest& request,
+ AAudioStreamConfiguration& config) {
+ aaudio_handle_t result;
+ StreamParameters params;
+ Status status = mDelegate->openStream(request.parcelable(),
+ ¶ms,
+ &result);
+ if (!status.isOk()) {
+ result = AAudioConvert_androidToAAudioResult(status.transactionError());
+ }
+ config = params;
+ return result;
}
aaudio_result_t AAudioBinderAdapter::closeStream(aaudio_handle_t streamHandle) {
- return mDelegate->closeStream(streamHandle);
+ aaudio_result_t result;
+ Status status = mDelegate->closeStream(streamHandle, &result);
+ if (!status.isOk()) {
+ result = AAudioConvert_androidToAAudioResult(status.transactionError());
+ }
+ return result;
}
aaudio_result_t AAudioBinderAdapter::getStreamDescription(aaudio_handle_t streamHandle,
- AudioEndpointParcelable &parcelable) {
- return mDelegate->getStreamDescription(streamHandle, parcelable);
+ AudioEndpointParcelable& endpointOut) {
+ aaudio_result_t result;
+ Endpoint endpoint;
+ Status status = mDelegate->getStreamDescription(streamHandle,
+ &endpoint,
+ &result);
+ if (!status.isOk()) {
+ result = AAudioConvert_androidToAAudioResult(status.transactionError());
+ }
+ endpointOut = std::move(endpoint);
+ return result;
}
aaudio_result_t AAudioBinderAdapter::startStream(aaudio_handle_t streamHandle) {
- return mDelegate->startStream(streamHandle);
+ aaudio_result_t result;
+ Status status = mDelegate->startStream(streamHandle, &result);
+ if (!status.isOk()) {
+ result = AAudioConvert_androidToAAudioResult(status.transactionError());
+ }
+ return result;
}
aaudio_result_t AAudioBinderAdapter::pauseStream(aaudio_handle_t streamHandle) {
- return mDelegate->pauseStream(streamHandle);
+ aaudio_result_t result;
+ Status status = mDelegate->pauseStream(streamHandle, &result);
+ if (!status.isOk()) {
+ result = AAudioConvert_androidToAAudioResult(status.transactionError());
+ }
+ return result;
}
aaudio_result_t AAudioBinderAdapter::stopStream(aaudio_handle_t streamHandle) {
- return mDelegate->stopStream(streamHandle);
+ aaudio_result_t result;
+ Status status = mDelegate->stopStream(streamHandle, &result);
+ if (!status.isOk()) {
+ result = AAudioConvert_androidToAAudioResult(status.transactionError());
+ }
+ return result;
}
aaudio_result_t AAudioBinderAdapter::flushStream(aaudio_handle_t streamHandle) {
- return mDelegate->flushStream(streamHandle);
+ aaudio_result_t result;
+ Status status = mDelegate->flushStream(streamHandle, &result);
+ if (!status.isOk()) {
+ result = AAudioConvert_androidToAAudioResult(status.transactionError());
+ }
+ return result;
}
aaudio_result_t AAudioBinderAdapter::registerAudioThread(aaudio_handle_t streamHandle,
pid_t clientThreadId,
int64_t periodNanoseconds) {
- return mDelegate->registerAudioThread(streamHandle, clientThreadId, periodNanoseconds);
+ aaudio_result_t result;
+ Status status = mDelegate->registerAudioThread(streamHandle, clientThreadId, periodNanoseconds, &result);
+ if (!status.isOk()) {
+ result = AAudioConvert_androidToAAudioResult(status.transactionError());
+ }
+ return result;
}
aaudio_result_t AAudioBinderAdapter::unregisterAudioThread(aaudio_handle_t streamHandle,
pid_t clientThreadId) {
- return mDelegate->unregisterAudioThread(streamHandle, clientThreadId);
+ aaudio_result_t result;
+ Status status = mDelegate->unregisterAudioThread(streamHandle, clientThreadId, &result);
+ if (!status.isOk()) {
+ result = AAudioConvert_androidToAAudioResult(status.transactionError());
+ }
+ return result;
}
} // namespace aaudio
diff --git a/media/libaaudio/src/binding/AAudioBinderAdapter.h b/media/libaaudio/src/binding/AAudioBinderAdapter.h
index 91dc6a6..5e9ab57 100644
--- a/media/libaaudio/src/binding/AAudioBinderAdapter.h
+++ b/media/libaaudio/src/binding/AAudioBinderAdapter.h
@@ -16,7 +16,7 @@
#pragma once
-#include <binding/IAAudioService.h>
+#include <aaudio/IAAudioService.h>
#include <binding/AAudioServiceInterface.h>
namespace aaudio {
@@ -30,7 +30,7 @@
*/
class AAudioBinderAdapter : public AAudioServiceInterface {
public:
- explicit AAudioBinderAdapter(android::IAAudioService* delegate);
+ explicit AAudioBinderAdapter(IAAudioService* delegate);
void registerClient(const android::sp<IAAudioClient>& client) override;
@@ -40,7 +40,7 @@
aaudio_result_t closeStream(aaudio_handle_t streamHandle) override;
aaudio_result_t getStreamDescription(aaudio_handle_t streamHandle,
- AudioEndpointParcelable& parcelable) override;
+ AudioEndpointParcelable& endpoint) override;
aaudio_result_t startStream(aaudio_handle_t streamHandle) override;
@@ -58,7 +58,7 @@
pid_t clientThreadId) override;
private:
- android::IAAudioService* const mDelegate;
+ IAAudioService* const mDelegate;
};
} // namespace aaudio
diff --git a/media/libaaudio/src/binding/AAudioBinderClient.cpp b/media/libaaudio/src/binding/AAudioBinderClient.cpp
index 7b0d31f..fa5a2da 100644
--- a/media/libaaudio/src/binding/AAudioBinderClient.cpp
+++ b/media/libaaudio/src/binding/AAudioBinderClient.cpp
@@ -19,35 +19,30 @@
//#define LOG_NDEBUG 0
#include <utils/Log.h>
-#include <binder/IInterface.h>
#include <binder/IServiceManager.h>
#include <binder/ProcessState.h>
#include <utils/Mutex.h>
#include <utils/RefBase.h>
#include <utils/Singleton.h>
-#include <media/AudioSystem.h>
-
#include <aaudio/AAudio.h>
#include "AudioEndpointParcelable.h"
-#include "binding/AAudioBinderClient.h"
-//#include "binding/AAudioStreamRequest.h"
-//#include "binding/AAudioStreamConfiguration.h"
-//#include "binding/IAAudioService.h"
-//#include "binding/AAudioServiceMessage.h"
-//#include "AAudioServiceInterface.h"
+#include "binding/AAudioBinderClient.h"
+
+#define AAUDIO_SERVICE_NAME "media.aaudio"
using android::String16;
using android::IServiceManager;
using android::defaultServiceManager;
using android::interface_cast;
using android::IInterface;
-using android::IAAudioService;
using android::Mutex;
using android::ProcessState;
using android::sp;
+using android::status_t;
using android::wp;
+using android::binder::Status;
using namespace aaudio;
@@ -67,20 +62,18 @@
AAudioBinderClient::~AAudioBinderClient() {
ALOGV("%s - destroying %p", __func__, this);
Mutex::Autolock _l(mServiceLock);
- if (mAAudioService != 0) {
- IInterface::asBinder(mAAudioService)->unlinkToDeath(mAAudioClient);
- }
}
// TODO Share code with other service clients.
// Helper function to get access to the "AAudioService" service.
// This code was modeled after frameworks/av/media/libaudioclient/AudioSystem.cpp
-const sp<IAAudioService> AAudioBinderClient::getAAudioService() {
+std::shared_ptr<AAudioServiceInterface> AAudioBinderClient::getAAudioService() {
+ std::shared_ptr<AAudioServiceInterface> result;
sp<IAAudioService> aaudioService;
bool needToRegister = false;
{
Mutex::Autolock _l(mServiceLock);
- if (mAAudioService.get() == nullptr) {
+ if (mAdapter == nullptr) {
sp<IBinder> binder;
sp<IServiceManager> sm = defaultServiceManager();
// Try several times to get the service.
@@ -99,7 +92,8 @@
if (status != NO_ERROR) {
ALOGE("%s() - linkToDeath() returned %d", __func__, status);
}
- mAAudioService = interface_cast<IAAudioService>(binder);
+ aaudioService = interface_cast<IAAudioService>(binder);
+ mAdapter.reset(new Adapter(aaudioService, mAAudioClient));
needToRegister = true;
// Make sure callbacks can be received by mAAudioClient
ProcessState::self()->startThreadPool();
@@ -107,18 +101,18 @@
ALOGE("AAudioBinderClient could not connect to %s", AAUDIO_SERVICE_NAME);
}
}
- aaudioService = mAAudioService;
+ result = mAdapter;
}
// Do this outside the mutex lock.
if (needToRegister && aaudioService.get() != nullptr) { // new client?
aaudioService->registerClient(mAAudioClient);
}
- return aaudioService;
+ return result;
}
void AAudioBinderClient::dropAAudioService() {
Mutex::Autolock _l(mServiceLock);
- mAAudioService.clear(); // force a reconnect
+ mAdapter.reset();
}
/**
@@ -127,13 +121,13 @@
* @return handle to the stream or a negative error
*/
aaudio_handle_t AAudioBinderClient::openStream(const AAudioStreamRequest &request,
- AAudioStreamConfiguration &configurationOutput) {
+ AAudioStreamConfiguration &configuration) {
aaudio_handle_t stream;
for (int i = 0; i < 2; i++) {
- const sp<IAAudioService> &service = getAAudioService();
+ std::shared_ptr<AAudioServiceInterface> service = getAAudioService();
if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE;
- stream = service->openStream(request, configurationOutput);
+ stream = service->openStream(request, configuration);
if (stream == AAUDIO_ERROR_NO_SERVICE) {
ALOGE("openStream lost connection to AAudioService.");
@@ -146,8 +140,9 @@
}
aaudio_result_t AAudioBinderClient::closeStream(aaudio_handle_t streamHandle) {
- const sp<IAAudioService> service = getAAudioService();
+ std::shared_ptr<AAudioServiceInterface> service = getAAudioService();
if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE;
+
return service->closeStream(streamHandle);
}
@@ -155,33 +150,38 @@
* used to communicate with the underlying HAL or Service.
*/
aaudio_result_t AAudioBinderClient::getStreamDescription(aaudio_handle_t streamHandle,
- AudioEndpointParcelable &parcelable) {
- const sp<IAAudioService> service = getAAudioService();
+ AudioEndpointParcelable& endpointOut) {
+ std::shared_ptr<AAudioServiceInterface> service = getAAudioService();
if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE;
- return service->getStreamDescription(streamHandle, parcelable);
+
+ return service->getStreamDescription(streamHandle, endpointOut);
}
aaudio_result_t AAudioBinderClient::startStream(aaudio_handle_t streamHandle) {
- const sp<IAAudioService> service = getAAudioService();
+ std::shared_ptr<AAudioServiceInterface> service = getAAudioService();
if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE;
+
return service->startStream(streamHandle);
}
aaudio_result_t AAudioBinderClient::pauseStream(aaudio_handle_t streamHandle) {
- const sp<IAAudioService> service = getAAudioService();
+ std::shared_ptr<AAudioServiceInterface> service = getAAudioService();
if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE;
+
return service->pauseStream(streamHandle);
}
aaudio_result_t AAudioBinderClient::stopStream(aaudio_handle_t streamHandle) {
- const sp<IAAudioService> service = getAAudioService();
+ std::shared_ptr<AAudioServiceInterface> service = getAAudioService();
if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE;
+
return service->stopStream(streamHandle);
}
aaudio_result_t AAudioBinderClient::flushStream(aaudio_handle_t streamHandle) {
- const sp<IAAudioService> service = getAAudioService();
+ std::shared_ptr<AAudioServiceInterface> service = getAAudioService();
if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE;
+
return service->flushStream(streamHandle);
}
@@ -191,17 +191,16 @@
aaudio_result_t AAudioBinderClient::registerAudioThread(aaudio_handle_t streamHandle,
pid_t clientThreadId,
int64_t periodNanoseconds) {
- const sp<IAAudioService> service = getAAudioService();
+ std::shared_ptr<AAudioServiceInterface> service = getAAudioService();
if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE;
- return service->registerAudioThread(streamHandle,
- clientThreadId,
- periodNanoseconds);
+
+ return service->registerAudioThread(streamHandle, clientThreadId, periodNanoseconds);
}
aaudio_result_t AAudioBinderClient::unregisterAudioThread(aaudio_handle_t streamHandle,
pid_t clientThreadId) {
- const sp<IAAudioService> service = getAAudioService();
+ std::shared_ptr<AAudioServiceInterface> service = getAAudioService();
if (service.get() == nullptr) return AAUDIO_ERROR_NO_SERVICE;
- return service->unregisterAudioThread(streamHandle,
- clientThreadId);
+
+ return service->unregisterAudioThread(streamHandle, clientThreadId);
}
diff --git a/media/libaaudio/src/binding/AAudioBinderClient.h b/media/libaaudio/src/binding/AAudioBinderClient.h
index a9a621e..6a7b639 100644
--- a/media/libaaudio/src/binding/AAudioBinderClient.h
+++ b/media/libaaudio/src/binding/AAudioBinderClient.h
@@ -21,13 +21,15 @@
#include <utils/Singleton.h>
#include <aaudio/AAudio.h>
+#include <binder/IInterface.h>
+
#include "aaudio/BnAAudioClient.h"
-#include "AAudioServiceDefinitions.h"
+#include "aaudio/IAAudioService.h"
#include "AAudioServiceInterface.h"
+#include "binding/AAudioBinderAdapter.h"
#include "binding/AAudioStreamRequest.h"
-#include "binding/AAudioStreamConfiguration.h"
#include "binding/AudioEndpointParcelable.h"
-#include "binding/IAAudioService.h"
+#include "core/AAudioStreamParameters.h"
/**
* Implements the AAudioServiceInterface by talking to the service through Binder.
@@ -45,10 +47,6 @@
virtual ~AAudioBinderClient();
- const android::sp<android::IAAudioService> getAAudioService();
-
- void dropAAudioService();
-
void registerClient(const android::sp<IAAudioClient>& client __unused) override {}
/**
@@ -65,7 +63,7 @@
* used to communicate with the underlying HAL or Service.
*/
aaudio_result_t getStreamDescription(aaudio_handle_t streamHandle,
- AudioEndpointParcelable &parcelable) override;
+ AudioEndpointParcelable &endpointOut) override;
/**
* Start the flow of data.
@@ -116,8 +114,7 @@
ALOGW("onStreamChange called!");
}
- class AAudioClient : public android::IBinder::DeathRecipient , public BnAAudioClient
- {
+ class AAudioClient : public android::IBinder::DeathRecipient, public BnAAudioClient {
public:
AAudioClient(android::wp<AAudioBinderClient> aaudioBinderClient)
: mBinderClient(aaudioBinderClient) {
@@ -145,11 +142,54 @@
android::wp<AAudioBinderClient> mBinderClient;
};
-private:
+ // This adapter is used to convert the binder interface (delegate) to the AudioServiceInterface
+ // conventions (translating between data types and respective parcelables, translating error
+ // codes and calling conventions).
+ // The adapter also owns the underlying service object and is responsible to unlink its death
+ // listener when destroyed.
+ class Adapter : public AAudioBinderAdapter {
+ public:
+ Adapter(const android::sp<IAAudioService>& delegate,
+ const android::sp<AAudioClient>& aaudioClient)
+ : AAudioBinderAdapter(delegate.get()),
+ mDelegate(delegate),
+ mAAudioClient(aaudioClient) {}
- android::Mutex mServiceLock;
- android::sp<android::IAAudioService> mAAudioService;
- android::sp<AAudioClient> mAAudioClient;
+ virtual ~Adapter() {
+ if (mDelegate != nullptr) {
+ android::IInterface::asBinder(mDelegate)->unlinkToDeath(mAAudioClient);
+ }
+ }
+
+ // This should never be called (call is rejected at the AudioBinderClient level).
+ aaudio_result_t startClient(aaudio_handle_t streamHandle __unused,
+ const android::AudioClient& client __unused,
+ const audio_attributes_t* attr __unused,
+ audio_port_handle_t* clientHandle __unused) override {
+ LOG_ALWAYS_FATAL("Shouldn't get here");
+ return AAUDIO_ERROR_UNAVAILABLE;
+ }
+
+ // This should never be called (call is rejected at the AudioBinderClient level).
+ aaudio_result_t stopClient(aaudio_handle_t streamHandle __unused,
+ audio_port_handle_t clientHandle __unused) override {
+ LOG_ALWAYS_FATAL("Shouldn't get here");
+ return AAUDIO_ERROR_UNAVAILABLE;
+ }
+
+ private:
+ android::sp<IAAudioService> mDelegate;
+ android::sp<AAudioClient> mAAudioClient;
+ };
+
+private:
+ android::Mutex mServiceLock;
+ std::shared_ptr<AAudioServiceInterface> mAdapter;
+ android::sp<AAudioClient> mAAudioClient;
+
+ std::shared_ptr<AAudioServiceInterface> getAAudioService();
+
+ void dropAAudioService();
};
diff --git a/media/libaaudio/src/binding/AAudioStreamConfiguration.cpp b/media/libaaudio/src/binding/AAudioStreamConfiguration.cpp
index b785f88..2d501ef 100644
--- a/media/libaaudio/src/binding/AAudioStreamConfiguration.cpp
+++ b/media/libaaudio/src/binding/AAudioStreamConfiguration.cpp
@@ -23,101 +23,66 @@
#include <sys/mman.h>
#include <aaudio/AAudio.h>
-#include <binder/Parcel.h>
-#include <binder/Parcelable.h>
-
#include "binding/AAudioStreamConfiguration.h"
-using android::NO_ERROR;
-using android::status_t;
-using android::Parcel;
-using android::Parcelable;
-
using namespace aaudio;
-AAudioStreamConfiguration::AAudioStreamConfiguration() {}
-AAudioStreamConfiguration::~AAudioStreamConfiguration() {}
+using android::media::audio::common::AudioFormat;
-status_t AAudioStreamConfiguration::writeToParcel(Parcel* parcel) const {
- status_t status;
-
- status = parcel->writeInt32(getDeviceId());
- if (status != NO_ERROR) goto error;
- status = parcel->writeInt32(getSampleRate());
- if (status != NO_ERROR) goto error;
- status = parcel->writeInt32(getSamplesPerFrame());
- if (status != NO_ERROR) goto error;
- status = parcel->writeInt32((int32_t) getSharingMode());
- if (status != NO_ERROR) goto error;
- status = parcel->writeInt32((int32_t) getFormat());
- if (status != NO_ERROR) goto error;
-
- status = parcel->writeInt32((int32_t) getDirection());
- if (status != NO_ERROR) goto error;
- status = parcel->writeInt32(getBufferCapacity());
- if (status != NO_ERROR) goto error;
- status = parcel->writeInt32((int32_t) getUsage());
- if (status != NO_ERROR) goto error;
- status = parcel->writeInt32((int32_t) getContentType());
- if (status != NO_ERROR) goto error;
- status = parcel->writeInt32((int32_t) getInputPreset());
- if (status != NO_ERROR) goto error;
- status = parcel->writeInt32((int32_t) getAllowedCapturePolicy());
- if (status != NO_ERROR) goto error;
- status = parcel->writeInt32(getSessionId());
- if (status != NO_ERROR) goto error;
- status = parcel->writeInt32(isPrivacySensitive() ? 1 : 0);
- if (status != NO_ERROR) goto error;
- return NO_ERROR;
-error:
- ALOGE("%s(): write failed = %d", __func__, status);
- return status;
+AAudioStreamConfiguration::AAudioStreamConfiguration(const StreamParameters& parcelable) {
+ setSamplesPerFrame(parcelable.samplesPerFrame);
+ setSampleRate(parcelable.sampleRate);
+ setDeviceId(parcelable.deviceId);
+ static_assert(sizeof(aaudio_sharing_mode_t) == sizeof(parcelable.sharingMode));
+ setSharingMode(parcelable.sharingMode);
+ static_assert(sizeof(audio_format_t) == sizeof(parcelable.audioFormat));
+ setFormat(static_cast<audio_format_t>(parcelable.audioFormat));
+ static_assert(sizeof(aaudio_direction_t) == sizeof(parcelable.direction));
+ setDirection(parcelable.direction);
+ static_assert(sizeof(audio_usage_t) == sizeof(parcelable.usage));
+ setUsage(parcelable.usage);
+ static_assert(sizeof(aaudio_content_type_t) == sizeof(parcelable.contentType));
+ setContentType(parcelable.contentType);
+ static_assert(sizeof(aaudio_input_preset_t) == sizeof(parcelable.inputPreset));
+ setInputPreset(parcelable.inputPreset);
+ setBufferCapacity(parcelable.bufferCapacity);
+ static_assert(
+ sizeof(aaudio_allowed_capture_policy_t) == sizeof(parcelable.allowedCapturePolicy));
+ setAllowedCapturePolicy(parcelable.allowedCapturePolicy);
+ static_assert(sizeof(aaudio_session_id_t) == sizeof(parcelable.sessionId));
+ setSessionId(parcelable.sessionId);
+ setPrivacySensitive(parcelable.isPrivacySensitive);
}
-status_t AAudioStreamConfiguration::readFromParcel(const Parcel* parcel) {
- int32_t value;
- status_t status = parcel->readInt32(&value);
- if (status != NO_ERROR) goto error;
- setDeviceId(value);
- status = parcel->readInt32(&value);
- if (status != NO_ERROR) goto error;
- setSampleRate(value);
- status = parcel->readInt32(&value);
- if (status != NO_ERROR) goto error;
- setSamplesPerFrame(value);
- status = parcel->readInt32(&value);
- if (status != NO_ERROR) goto error;
- setSharingMode((aaudio_sharing_mode_t) value);
- status = parcel->readInt32(&value);
- if (status != NO_ERROR) goto error;
- setFormat((audio_format_t) value);
+AAudioStreamConfiguration&
+AAudioStreamConfiguration::operator=(const StreamParameters& parcelable) {
+ this->~AAudioStreamConfiguration();
+ new (this) AAudioStreamConfiguration(parcelable);
+ return *this;
+}
- status = parcel->readInt32(&value);
- if (status != NO_ERROR) goto error;
- setDirection((aaudio_direction_t) value);
- status = parcel->readInt32(&value);
- if (status != NO_ERROR) goto error;
- setBufferCapacity(value);
- status = parcel->readInt32(&value);
- if (status != NO_ERROR) goto error;
- setUsage((aaudio_usage_t) value);
- status = parcel->readInt32(&value);
- if (status != NO_ERROR) goto error;
- setContentType((aaudio_content_type_t) value);
- status = parcel->readInt32(&value);
- if (status != NO_ERROR) goto error;
- setInputPreset((aaudio_input_preset_t) value);
- status = parcel->readInt32(&value);
- if (status != NO_ERROR) goto error;
- setAllowedCapturePolicy((aaudio_allowed_capture_policy_t) value);
- status = parcel->readInt32(&value);
- if (status != NO_ERROR) goto error;
- setSessionId(value);
- status = parcel->readInt32(&value);
- if (status != NO_ERROR) goto error;
- setPrivacySensitive(value == 1);
- return NO_ERROR;
-error:
- ALOGE("%s(): read failed = %d", __func__, status);
- return status;
+StreamParameters AAudioStreamConfiguration::parcelable() const {
+ StreamParameters result;
+ result.samplesPerFrame = getSamplesPerFrame();
+ result.sampleRate = getSampleRate();
+ result.deviceId = getDeviceId();
+ static_assert(sizeof(aaudio_sharing_mode_t) == sizeof(result.sharingMode));
+ result.sharingMode = getSharingMode();
+ static_assert(sizeof(audio_format_t) == sizeof(result.audioFormat));
+ result.audioFormat = static_cast<AudioFormat>(getFormat());
+ static_assert(sizeof(aaudio_direction_t) == sizeof(result.direction));
+ result.direction = getDirection();
+ static_assert(sizeof(audio_usage_t) == sizeof(result.usage));
+ result.usage = getUsage();
+ static_assert(sizeof(aaudio_content_type_t) == sizeof(result.contentType));
+ result.contentType = getContentType();
+ static_assert(sizeof(aaudio_input_preset_t) == sizeof(result.inputPreset));
+ result.inputPreset = getInputPreset();
+ result.bufferCapacity = getBufferCapacity();
+ static_assert(sizeof(aaudio_allowed_capture_policy_t) == sizeof(result.allowedCapturePolicy));
+ result.allowedCapturePolicy = getAllowedCapturePolicy();
+ static_assert(sizeof(aaudio_session_id_t) == sizeof(result.sessionId));
+ result.sessionId = getSessionId();
+ result.isPrivacySensitive = isPrivacySensitive();
+ return result;
}
diff --git a/media/libaaudio/src/binding/AAudioStreamConfiguration.h b/media/libaaudio/src/binding/AAudioStreamConfiguration.h
index b324896..f428eb0 100644
--- a/media/libaaudio/src/binding/AAudioStreamConfiguration.h
+++ b/media/libaaudio/src/binding/AAudioStreamConfiguration.h
@@ -20,24 +20,24 @@
#include <stdint.h>
#include <aaudio/AAudio.h>
+#include <aaudio/StreamParameters.h>
#include <binder/Parcel.h>
#include <binder/Parcelable.h>
#include "core/AAudioStreamParameters.h"
-using android::status_t;
-using android::Parcel;
-using android::Parcelable;
-
namespace aaudio {
-class AAudioStreamConfiguration : public AAudioStreamParameters, public Parcelable {
+// This is a holder for AAudioStreamParameters, which allows conversion to/from it parcelable
+// representation, StreamParameters.
+class AAudioStreamConfiguration : public AAudioStreamParameters {
public:
- AAudioStreamConfiguration();
- virtual ~AAudioStreamConfiguration();
+ AAudioStreamConfiguration() = default;
- virtual status_t writeToParcel(Parcel* parcel) const override;
+ explicit AAudioStreamConfiguration(const StreamParameters& parcelable);
- virtual status_t readFromParcel(const Parcel* parcel) override;
+ AAudioStreamConfiguration& operator=(const StreamParameters& parcelable);
+
+ StreamParameters parcelable() const;
};
} /* namespace aaudio */
diff --git a/media/libaaudio/src/binding/AAudioStreamRequest.cpp b/media/libaaudio/src/binding/AAudioStreamRequest.cpp
index c30c5b9..536395a 100644
--- a/media/libaaudio/src/binding/AAudioStreamRequest.cpp
+++ b/media/libaaudio/src/binding/AAudioStreamRequest.cpp
@@ -21,67 +21,32 @@
#include <stdint.h>
#include <sys/mman.h>
-#include <binder/Parcel.h>
-#include <binder/Parcelable.h>
#include <aaudio/AAudio.h>
#include "binding/AAudioStreamConfiguration.h"
#include "binding/AAudioStreamRequest.h"
-using android::NO_ERROR;
-using android::status_t;
-using android::Parcel;
-using android::Parcelable;
-
using namespace aaudio;
-AAudioStreamRequest::AAudioStreamRequest()
- : mConfiguration()
- {}
-
-AAudioStreamRequest::~AAudioStreamRequest() {}
-
-status_t AAudioStreamRequest::writeToParcel(Parcel* parcel) const {
- status_t status = parcel->writeInt32((int32_t) mUserId);
- if (status != NO_ERROR) goto error;
-
- status = parcel->writeBool(mSharingModeMatchRequired);
- if (status != NO_ERROR) goto error;
-
- status = parcel->writeBool(mInService);
- if (status != NO_ERROR) goto error;
-
- status = mConfiguration.writeToParcel(parcel);
- if (status != NO_ERROR) goto error;
-
- return NO_ERROR;
-
-error:
- ALOGE("writeToParcel(): write failed = %d", status);
- return status;
+AAudioStreamRequest::AAudioStreamRequest(const StreamRequest& parcelable) :
+ mConfiguration(std::move(parcelable.params)),
+ mUserId(parcelable.userId),
+ mProcessId(parcelable.processId),
+ mSharingModeMatchRequired(parcelable.sharingModeMatchRequired),
+ mInService(parcelable.inService) {
+ static_assert(sizeof(mUserId) == sizeof(parcelable.userId));
+ static_assert(sizeof(mProcessId) == sizeof(parcelable.processId));
}
-status_t AAudioStreamRequest::readFromParcel(const Parcel* parcel) {
- int32_t temp;
- status_t status = parcel->readInt32(&temp);
- if (status != NO_ERROR) goto error;
- mUserId = (uid_t) temp;
-
- status = parcel->readBool(&mSharingModeMatchRequired);
- if (status != NO_ERROR) goto error;
-
- status = parcel->readBool(&mInService);
- if (status != NO_ERROR) goto error;
-
- status = mConfiguration.readFromParcel(parcel);
- if (status != NO_ERROR) goto error;
-
- return NO_ERROR;
-
-error:
- ALOGE("readFromParcel(): read failed = %d", status);
- return status;
+StreamRequest AAudioStreamRequest::parcelable() const {
+ StreamRequest result;
+ result.params = std::move(mConfiguration).parcelable();
+ result.userId = mUserId;
+ result.processId = mProcessId;
+ result.sharingModeMatchRequired = mSharingModeMatchRequired;
+ result.inService = mInService;
+ return result;
}
aaudio_result_t AAudioStreamRequest::validate() const {
diff --git a/media/libaaudio/src/binding/AAudioStreamRequest.h b/media/libaaudio/src/binding/AAudioStreamRequest.h
index 492f69d..31d3ea1 100644
--- a/media/libaaudio/src/binding/AAudioStreamRequest.h
+++ b/media/libaaudio/src/binding/AAudioStreamRequest.h
@@ -20,21 +20,18 @@
#include <stdint.h>
#include <aaudio/AAudio.h>
-#include <binder/Parcel.h>
-#include <binder/Parcelable.h>
+#include <aaudio/StreamRequest.h>
#include "binding/AAudioStreamConfiguration.h"
-using android::status_t;
-using android::Parcel;
-using android::Parcelable;
-
namespace aaudio {
-class AAudioStreamRequest : public Parcelable {
+class AAudioStreamRequest {
public:
- AAudioStreamRequest();
- virtual ~AAudioStreamRequest();
+ AAudioStreamRequest() = default;
+
+ // Construct based on a parcelable representation.
+ explicit AAudioStreamRequest(const StreamRequest& parcelable);
uid_t getUserId() const {
return mUserId;
@@ -76,15 +73,14 @@
mInService = inService;
}
- virtual status_t writeToParcel(Parcel* parcel) const override;
-
- virtual status_t readFromParcel(const Parcel* parcel) override;
-
aaudio_result_t validate() const;
void dump() const;
-protected:
+ // Extract a parcelable representation of this object.
+ StreamRequest parcelable() const;
+
+private:
AAudioStreamConfiguration mConfiguration;
uid_t mUserId = (uid_t) -1;
pid_t mProcessId = (pid_t) -1;
diff --git a/media/libaaudio/src/binding/AudioEndpointParcelable.cpp b/media/libaaudio/src/binding/AudioEndpointParcelable.cpp
index 61d7d27..aa4ac27 100644
--- a/media/libaaudio/src/binding/AudioEndpointParcelable.cpp
+++ b/media/libaaudio/src/binding/AudioEndpointParcelable.cpp
@@ -29,22 +29,43 @@
#include "binding/AudioEndpointParcelable.h"
using android::base::unique_fd;
+using android::media::SharedFileRegion;
using android::NO_ERROR;
using android::status_t;
-using android::Parcel;
-using android::Parcelable;
using namespace aaudio;
-/**
- * Container for information about the message queues plus
- * general stream information needed by AAudio clients.
- * It contains no addresses, just sizes, offsets and file descriptors for
- * shared memory that can be passed through Binder.
- */
-AudioEndpointParcelable::AudioEndpointParcelable() {}
+AudioEndpointParcelable::AudioEndpointParcelable(Endpoint&& parcelable)
+ : mUpMessageQueueParcelable(std::move(parcelable.upMessageQueueParcelable)),
+ mDownMessageQueueParcelable(std::move(parcelable.downMessageQueueParcelable)),
+ mUpDataQueueParcelable(std::move(parcelable.upDataQueueParcelable)),
+ mDownDataQueueParcelable(std::move(parcelable.downDataQueueParcelable)),
+ mNumSharedMemories(parcelable.sharedMemories.size()) {
+ for (size_t i = 0; i < parcelable.sharedMemories.size() && i < MAX_SHARED_MEMORIES; ++i) {
+ // Re-construct.
+ mSharedMemories[i].~SharedMemoryParcelable();
+ new(&mSharedMemories[i]) SharedMemoryParcelable(std::move(parcelable.sharedMemories[i]));
+ }
+}
-AudioEndpointParcelable::~AudioEndpointParcelable() {}
+AudioEndpointParcelable& AudioEndpointParcelable::operator=(Endpoint&& parcelable) {
+ this->~AudioEndpointParcelable();
+ new(this) AudioEndpointParcelable(std::move(parcelable));
+ return *this;
+}
+
+Endpoint AudioEndpointParcelable::parcelable()&& {
+ Endpoint result;
+ result.upMessageQueueParcelable = std::move(mUpMessageQueueParcelable).parcelable();
+ result.downMessageQueueParcelable = std::move(mDownMessageQueueParcelable).parcelable();
+ result.upDataQueueParcelable = std::move(mUpDataQueueParcelable).parcelable();
+ result.downDataQueueParcelable = std::move(mDownDataQueueParcelable).parcelable();
+ result.sharedMemories.reserve(std::min(mNumSharedMemories, MAX_SHARED_MEMORIES));
+ for (size_t i = 0; i < mNumSharedMemories && i < MAX_SHARED_MEMORIES; ++i) {
+ result.sharedMemories.emplace_back(std::move(mSharedMemories[i]).parcelable());
+ }
+ return result;
+}
/**
* Add the file descriptor to the table.
@@ -60,60 +81,6 @@
return index;
}
-/**
- * The read and write must be symmetric.
- */
-status_t AudioEndpointParcelable::writeToParcel(Parcel* parcel) const {
- status_t status = AAudioConvert_aaudioToAndroidStatus(validate());
- if (status != NO_ERROR) goto error;
-
- status = parcel->writeInt32(mNumSharedMemories);
- if (status != NO_ERROR) goto error;
-
- for (int i = 0; i < mNumSharedMemories; i++) {
- status = mSharedMemories[i].writeToParcel(parcel);
- if (status != NO_ERROR) goto error;
- }
- status = mUpMessageQueueParcelable.writeToParcel(parcel);
- if (status != NO_ERROR) goto error;
- status = mDownMessageQueueParcelable.writeToParcel(parcel);
- if (status != NO_ERROR) goto error;
- status = mUpDataQueueParcelable.writeToParcel(parcel);
- if (status != NO_ERROR) goto error;
- status = mDownDataQueueParcelable.writeToParcel(parcel);
- if (status != NO_ERROR) goto error;
-
- return NO_ERROR;
-
-error:
- ALOGE("%s returning %d", __func__, status);
- return status;
-}
-
-status_t AudioEndpointParcelable::readFromParcel(const Parcel* parcel) {
- status_t status = parcel->readInt32(&mNumSharedMemories);
- if (status != NO_ERROR) goto error;
-
- for (int i = 0; i < mNumSharedMemories; i++) {
- mSharedMemories[i].readFromParcel(parcel);
- if (status != NO_ERROR) goto error;
- }
- status = mUpMessageQueueParcelable.readFromParcel(parcel);
- if (status != NO_ERROR) goto error;
- status = mDownMessageQueueParcelable.readFromParcel(parcel);
- if (status != NO_ERROR) goto error;
- status = mUpDataQueueParcelable.readFromParcel(parcel);
- if (status != NO_ERROR) goto error;
- status = mDownDataQueueParcelable.readFromParcel(parcel);
- if (status != NO_ERROR) goto error;
-
- return AAudioConvert_aaudioToAndroidStatus(validate());
-
-error:
- ALOGE("%s returning %d", __func__, status);
- return status;
-}
-
aaudio_result_t AudioEndpointParcelable::resolve(EndpointDescriptor *descriptor) {
aaudio_result_t result = mUpMessageQueueParcelable.resolve(mSharedMemories,
&descriptor->upMessageQueueDescriptor);
diff --git a/media/libaaudio/src/binding/AudioEndpointParcelable.h b/media/libaaudio/src/binding/AudioEndpointParcelable.h
index e4f8b9e..5237a1a 100644
--- a/media/libaaudio/src/binding/AudioEndpointParcelable.h
+++ b/media/libaaudio/src/binding/AudioEndpointParcelable.h
@@ -20,16 +20,13 @@
#include <stdint.h>
//#include <sys/mman.h>
+#include <aaudio/Endpoint.h>
#include <android-base/unique_fd.h>
-#include <binder/Parcel.h>
-#include <binder/Parcelable.h>
#include "binding/AAudioServiceDefinitions.h"
#include "binding/RingBufferParcelable.h"
using android::status_t;
-using android::Parcel;
-using android::Parcelable;
namespace aaudio {
@@ -39,10 +36,15 @@
* It contains no addresses, just sizes, offsets and file descriptors for
* shared memory that can be passed through Binder.
*/
-class AudioEndpointParcelable : public Parcelable {
+class AudioEndpointParcelable {
public:
- AudioEndpointParcelable();
- virtual ~AudioEndpointParcelable();
+ AudioEndpointParcelable() = default;
+
+ // Ctor/assignment from a parcelable representation.
+ // Since the parcelable object owns unique FDs (for shared memory blocks), move semantics are
+ // provided to avoid the need to dupe.
+ AudioEndpointParcelable(Endpoint&& parcelable);
+ AudioEndpointParcelable& operator=(Endpoint&& parcelable);
/**
* Add the file descriptor to the table.
@@ -50,16 +52,17 @@
*/
int32_t addFileDescriptor(const android::base::unique_fd& fd, int32_t sizeInBytes);
- virtual status_t writeToParcel(Parcel* parcel) const override;
-
- virtual status_t readFromParcel(const Parcel* parcel) override;
-
aaudio_result_t resolve(EndpointDescriptor *descriptor);
aaudio_result_t close();
void dump();
+ // Extract a parcelable representation of this object.
+ // Since our shared memory objects own a unique FD, move semantics are provided to avoid the
+ // need to dupe.
+ Endpoint parcelable()&&;
+
public: // TODO add getters
// Set capacityInFrames to zero if Queue is unused.
RingBufferParcelable mUpMessageQueueParcelable; // server to client
diff --git a/media/libaaudio/src/binding/IAAudioService.cpp b/media/libaaudio/src/binding/IAAudioService.cpp
deleted file mode 100644
index 13d5bf8..0000000
--- a/media/libaaudio/src/binding/IAAudioService.cpp
+++ /dev/null
@@ -1,424 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "AAudio"
-//#define LOG_NDEBUG 0
-#include <utils/Log.h>
-
-#include <aaudio/AAudio.h>
-#include <binder/IPCThreadState.h>
-
-#include "binding/AudioEndpointParcelable.h"
-#include "binding/AAudioStreamRequest.h"
-#include "binding/AAudioServiceDefinitions.h"
-#include "binding/AAudioStreamConfiguration.h"
-#include "binding/IAAudioService.h"
-#include "utility/AAudioUtilities.h"
-
-namespace android {
-
-using aaudio::aaudio_handle_t;
-
-/**
- * This is used by the AAudio Client to talk to the AAudio Service.
- *
- * The order of parameters in the Parcels must match with code in AAudioService.cpp.
- */
-class BpAAudioService : public BpInterface<IAAudioService>
-{
-public:
- explicit BpAAudioService(const sp<IBinder>& impl)
- : BpInterface<IAAudioService>(impl)
- {
- }
-
- void registerClient(const sp<aaudio::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());
- // request.dump();
- request.writeToParcel(&data);
- status_t err = remote()->transact(OPEN_STREAM, data, &reply);
- if (err != NO_ERROR) {
- ALOGE("BpAAudioService::client openStream transact failed %d", err);
- return AAudioConvert_androidToAAudioResult(err);
- }
- // parse reply
- aaudio_handle_t stream;
- err = reply.readInt32(&stream);
- if (err != NO_ERROR) {
- ALOGE("BpAAudioService::client transact(OPEN_STREAM) readInt %d", err);
- return AAudioConvert_androidToAAudioResult(err);
- } else if (stream < 0) {
- return stream;
- }
- err = configurationOutput.readFromParcel(&reply);
- if (err != NO_ERROR) {
- ALOGE("BpAAudioService::client openStream readFromParcel failed %d", err);
- closeStream(stream);
- return AAudioConvert_androidToAAudioResult(err);
- }
- return stream;
- }
-
- virtual aaudio_result_t closeStream(aaudio_handle_t streamHandle) override {
- Parcel data, reply;
- // send command
- data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
- data.writeInt32(streamHandle);
- status_t err = remote()->transact(CLOSE_STREAM, data, &reply);
- if (err != NO_ERROR) {
- ALOGE("BpAAudioService::client closeStream transact failed %d", err);
- return AAudioConvert_androidToAAudioResult(err);
- }
- // parse reply
- aaudio_result_t res;
- reply.readInt32(&res);
- return res;
- }
-
- virtual aaudio_result_t getStreamDescription(aaudio_handle_t streamHandle,
- aaudio::AudioEndpointParcelable &parcelable) {
- Parcel data, reply;
- // send command
- data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
- data.writeInt32(streamHandle);
- status_t err = remote()->transact(GET_STREAM_DESCRIPTION, data, &reply);
- if (err != NO_ERROR) {
- ALOGE("BpAAudioService::client transact(GET_STREAM_DESCRIPTION) returns %d", err);
- return AAudioConvert_androidToAAudioResult(err);
- }
- // parse reply
- aaudio_result_t result;
- err = reply.readInt32(&result);
- if (err != NO_ERROR) {
- ALOGE("BpAAudioService::client transact(GET_STREAM_DESCRIPTION) readInt %d", err);
- return AAudioConvert_androidToAAudioResult(err);
- } else if (result != AAUDIO_OK) {
- ALOGE("BpAAudioService::client GET_STREAM_DESCRIPTION passed result %d", result);
- return result;
- }
- err = parcelable.readFromParcel(&reply);
- if (err != NO_ERROR) {
- ALOGE("BpAAudioService::client transact(GET_STREAM_DESCRIPTION) read endpoint %d", err);
- return AAudioConvert_androidToAAudioResult(err);
- }
- return result;
- }
-
- // TODO should we wait for a reply?
- virtual aaudio_result_t startStream(aaudio_handle_t streamHandle) override {
- Parcel data, reply;
- // send command
- data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
- data.writeInt32(streamHandle);
- status_t err = remote()->transact(START_STREAM, data, &reply);
- if (err != NO_ERROR) {
- return AAudioConvert_androidToAAudioResult(err);
- }
- // parse reply
- aaudio_result_t res;
- reply.readInt32(&res);
- return res;
- }
-
- virtual aaudio_result_t pauseStream(aaudio_handle_t streamHandle) override {
- Parcel data, reply;
- // send command
- data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
- data.writeInt32(streamHandle);
- status_t err = remote()->transact(PAUSE_STREAM, data, &reply);
- if (err != NO_ERROR) {
- return AAudioConvert_androidToAAudioResult(err);
- }
- // parse reply
- aaudio_result_t res;
- reply.readInt32(&res);
- return res;
- }
-
- virtual aaudio_result_t stopStream(aaudio_handle_t streamHandle) override {
- Parcel data, reply;
- // send command
- data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
- data.writeInt32(streamHandle);
- status_t err = remote()->transact(STOP_STREAM, data, &reply);
- if (err != NO_ERROR) {
- return AAudioConvert_androidToAAudioResult(err);
- }
- // parse reply
- aaudio_result_t res;
- reply.readInt32(&res);
- return res;
- }
-
- virtual aaudio_result_t flushStream(aaudio_handle_t streamHandle) override {
- Parcel data, reply;
- // send command
- data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
- data.writeInt32(streamHandle);
- status_t err = remote()->transact(FLUSH_STREAM, data, &reply);
- if (err != NO_ERROR) {
- return AAudioConvert_androidToAAudioResult(err);
- }
- // parse reply
- aaudio_result_t res;
- reply.readInt32(&res);
- return res;
- }
-
- virtual aaudio_result_t registerAudioThread(aaudio_handle_t streamHandle,
- pid_t clientThreadId,
- int64_t periodNanoseconds)
- override {
- Parcel data, reply;
- // send command
- data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
- data.writeInt32(streamHandle);
- data.writeInt32((int32_t) clientThreadId);
- data.writeInt64(periodNanoseconds);
- status_t err = remote()->transact(REGISTER_AUDIO_THREAD, data, &reply);
- if (err != NO_ERROR) {
- return AAudioConvert_androidToAAudioResult(err);
- }
- // parse reply
- aaudio_result_t res;
- reply.readInt32(&res);
- return res;
- }
-
- virtual aaudio_result_t unregisterAudioThread(aaudio_handle_t streamHandle,
- pid_t clientThreadId)
- override {
- Parcel data, reply;
- // send command
- data.writeInterfaceToken(IAAudioService::getInterfaceDescriptor());
- data.writeInt32(streamHandle);
- data.writeInt32((int32_t) clientThreadId);
- status_t err = remote()->transact(UNREGISTER_AUDIO_THREAD, data, &reply);
- if (err != NO_ERROR) {
- return AAudioConvert_androidToAAudioResult(err);
- }
- // parse reply
- aaudio_result_t res;
- reply.readInt32(&res);
- return res;
- }
-
-};
-
-// Implement an interface to the service.
-// This is here so that you don't have to link with libaaudio static library.
-IMPLEMENT_META_INTERFACE(AAudioService, "IAAudioService");
-
-// The order of parameters in the Parcels must match with code in BpAAudioService
-
-status_t BnAAudioService::onTransact(uint32_t code, const Parcel& data,
- Parcel* reply, uint32_t flags) {
- aaudio_handle_t streamHandle = 0;
- aaudio::AAudioStreamRequest request;
- aaudio::AAudioStreamConfiguration configuration;
- pid_t tid = 0;
- int64_t nanoseconds = 0;
- aaudio_result_t result = AAUDIO_OK;
- status_t status = NO_ERROR;
- ALOGV("BnAAudioService::onTransact(%i) %i", code, flags);
-
- switch(code) {
- case REGISTER_CLIENT: {
- CHECK_INTERFACE(IAAudioService, data, reply);
- sp<aaudio::IAAudioClient> client = interface_cast<aaudio::IAAudioClient>(
- data.readStrongBinder());
- // readStrongBinder() can return null
- if (client.get() == nullptr) {
- ALOGE("BnAAudioService::%s(REGISTER_CLIENT) client is NULL!", __func__);
- android_errorWriteLog(0x534e4554, "116230453");
- return DEAD_OBJECT;
- } else {
- registerClient(client);
- return NO_ERROR;
- }
- } break;
-
- case OPEN_STREAM: {
- CHECK_INTERFACE(IAAudioService, data, reply);
- request.readFromParcel(&data);
- result = request.validate();
- if (result != AAUDIO_OK) {
- streamHandle = result;
- } else {
- //ALOGD("BnAAudioService::client openStream request dump --------------------");
- //request.dump();
- // Override the uid and pid from the client in case they are incorrect.
- request.setUserId(IPCThreadState::self()->getCallingUid());
- request.setProcessId(IPCThreadState::self()->getCallingPid());
- 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);
- status = data.readInt32(&streamHandle);
- if (status != NO_ERROR) {
- ALOGE("BnAAudioService::%s(CLOSE_STREAM) streamHandle failed!", __func__);
- return status;
- }
- result = closeStream(streamHandle);
- //ALOGD("BnAAudioService::onTransact CLOSE_STREAM 0x%08X, result = %d",
- // streamHandle, result);
- reply->writeInt32(result);
- return NO_ERROR;
- } break;
-
- case GET_STREAM_DESCRIPTION: {
- CHECK_INTERFACE(IAAudioService, data, reply);
- status = data.readInt32(&streamHandle);
- if (status != NO_ERROR) {
- ALOGE("BnAAudioService::%s(GET_STREAM_DESCRIPTION) streamHandle failed!", __func__);
- return status;
- }
- aaudio::AudioEndpointParcelable parcelable;
- result = getStreamDescription(streamHandle, parcelable);
- if (result != AAUDIO_OK) {
- return AAudioConvert_aaudioToAndroidStatus(result);
- }
- status = reply->writeInt32(result);
- if (status != NO_ERROR) {
- return status;
- }
- return parcelable.writeToParcel(reply);
- } break;
-
- case START_STREAM: {
- CHECK_INTERFACE(IAAudioService, data, reply);
- status = data.readInt32(&streamHandle);
- if (status != NO_ERROR) {
- ALOGE("BnAAudioService::%s(START_STREAM) streamHandle failed!", __func__);
- return status;
- }
- result = startStream(streamHandle);
- ALOGV("BnAAudioService::onTransact START_STREAM 0x%08X, result = %d",
- streamHandle, result);
- reply->writeInt32(result);
- return NO_ERROR;
- } break;
-
- case PAUSE_STREAM: {
- CHECK_INTERFACE(IAAudioService, data, reply);
- status = data.readInt32(&streamHandle);
- if (status != NO_ERROR) {
- ALOGE("BnAAudioService::%s(PAUSE_STREAM) streamHandle failed!", __func__);
- return status;
- }
- result = pauseStream(streamHandle);
- ALOGV("BnAAudioService::onTransact PAUSE_STREAM 0x%08X, result = %d",
- streamHandle, result);
- reply->writeInt32(result);
- return NO_ERROR;
- } break;
-
- case STOP_STREAM: {
- CHECK_INTERFACE(IAAudioService, data, reply);
- status = data.readInt32(&streamHandle);
- if (status != NO_ERROR) {
- ALOGE("BnAAudioService::%s(STOP_STREAM) streamHandle failed!", __func__);
- return status;
- }
- result = stopStream(streamHandle);
- ALOGV("BnAAudioService::onTransact STOP_STREAM 0x%08X, result = %d",
- streamHandle, result);
- reply->writeInt32(result);
- return NO_ERROR;
- } break;
-
- case FLUSH_STREAM: {
- CHECK_INTERFACE(IAAudioService, data, reply);
- status = data.readInt32(&streamHandle);
- if (status != NO_ERROR) {
- ALOGE("BnAAudioService::%s(FLUSH_STREAM) streamHandle failed!", __func__);
- return status;
- }
- result = flushStream(streamHandle);
- ALOGV("BnAAudioService::onTransact FLUSH_STREAM 0x%08X, result = %d",
- streamHandle, result);
- reply->writeInt32(result);
- return NO_ERROR;
- } break;
-
- case REGISTER_AUDIO_THREAD: {
- CHECK_INTERFACE(IAAudioService, data, reply);
- status = data.readInt32(&streamHandle);
- if (status != NO_ERROR) {
- ALOGE("BnAAudioService::%s(REGISTER_AUDIO_THREAD) streamHandle failed!", __func__);
- return status;
- }
- status = data.readInt32(&tid);
- if (status != NO_ERROR) {
- ALOGE("BnAAudioService::%s(REGISTER_AUDIO_THREAD) tid failed!", __func__);
- return status;
- }
- status = data.readInt64(&nanoseconds);
- if (status != NO_ERROR) {
- ALOGE("BnAAudioService::%s(REGISTER_AUDIO_THREAD) nanoseconds failed!", __func__);
- return status;
- }
- result = registerAudioThread(streamHandle, tid, nanoseconds);
- ALOGV("BnAAudioService::%s(REGISTER_AUDIO_THREAD) 0x%08X, result = %d",
- __func__, streamHandle, result);
- reply->writeInt32(result);
- return NO_ERROR;
- } break;
-
- case UNREGISTER_AUDIO_THREAD: {
- CHECK_INTERFACE(IAAudioService, data, reply);
- status = data.readInt32(&streamHandle);
- if (status != NO_ERROR) {
- ALOGE("BnAAudioService::%s(UNREGISTER_AUDIO_THREAD) streamHandle failed!", __func__);
- return status;
- }
- status = data.readInt32(&tid);
- if (status != NO_ERROR) {
- ALOGE("BnAAudioService::%s(UNREGISTER_AUDIO_THREAD) tid failed!", __func__);
- return status;
- }
- result = unregisterAudioThread(streamHandle, tid);
- ALOGV("BnAAudioService::onTransact UNREGISTER_AUDIO_THREAD 0x%08X, result = %d",
- streamHandle, result);
- reply->writeInt32(result);
- return NO_ERROR;
- } break;
-
- default:
- // ALOGW("BnAAudioService::onTransact not handled %u", code);
- return BBinder::onTransact(code, data, reply, flags);
- }
-}
-
-} /* namespace android */
diff --git a/media/libaaudio/src/binding/IAAudioService.h b/media/libaaudio/src/binding/IAAudioService.h
deleted file mode 100644
index 2649691..0000000
--- a/media/libaaudio/src/binding/IAAudioService.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_AAUDIO_IAAUDIO_SERVICE_H
-#define ANDROID_AAUDIO_IAAUDIO_SERVICE_H
-
-#include <stdint.h>
-#include <utils/RefBase.h>
-#include <binder/TextOutput.h>
-#include <binder/IInterface.h>
-
-#include <aaudio/AAudio.h>
-
-#include "aaudio/IAAudioClient.h"
-#include "binding/AAudioCommon.h"
-#include "binding/AAudioServiceDefinitions.h"
-#include "binding/AAudioStreamConfiguration.h"
-#include "binding/AAudioStreamRequest.h"
-#include "binding/AudioEndpointParcelable.h"
-
-namespace android {
-
-#define AAUDIO_SERVICE_NAME "media.aaudio"
-
-// Interface (our AIDL) - service methods called by client
-class IAAudioService : public IInterface {
-public:
-
- DECLARE_META_INTERFACE(AAudioService);
-
- // Register an object to receive audio input/output change and track notifications.
- // For a given calling pid, AAudio service disregards any registrations after the first.
- // Thus the IAAudioClient must be a singleton per process.
- virtual void registerClient(const sp<aaudio::IAAudioClient>& client) = 0;
-
- /**
- * @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
- */
- virtual aaudio::aaudio_handle_t openStream(const aaudio::AAudioStreamRequest &request,
- aaudio::AAudioStreamConfiguration &configurationOutput) = 0;
-
- virtual aaudio_result_t closeStream(aaudio::aaudio_handle_t streamHandle) = 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::aaudio_handle_t streamHandle,
- aaudio::AudioEndpointParcelable &parcelable) = 0;
-
- /**
- * Start the flow of data.
- * This is asynchronous. When complete, the service will send a STARTED event.
- */
- virtual aaudio_result_t startStream(aaudio::aaudio_handle_t streamHandle) = 0;
-
- /**
- * 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.
- */
- virtual aaudio_result_t pauseStream(aaudio::aaudio_handle_t streamHandle) = 0;
-
- /**
- * Stop the flow of data such that the data currently in the buffer is played.
- * This is asynchronous. When complete, the service will send a STOPPED event.
- */
- virtual aaudio_result_t stopStream(aaudio::aaudio_handle_t streamHandle) = 0;
-
- /**
- * Discard any data held by the underlying HAL or Service.
- * This is asynchronous. When complete, the service will send a FLUSHED event.
- */
- virtual aaudio_result_t flushStream(aaudio::aaudio_handle_t streamHandle) = 0;
-
- /**
- * Manage the specified thread as a low latency audio thread.
- */
- virtual aaudio_result_t registerAudioThread(aaudio::aaudio_handle_t streamHandle,
- pid_t clientThreadId,
- int64_t periodNanoseconds) = 0;
-
- virtual aaudio_result_t unregisterAudioThread(aaudio::aaudio_handle_t streamHandle,
- pid_t clientThreadId) = 0;
-};
-
-class BnAAudioService : public BnInterface<IAAudioService> {
-public:
- virtual status_t onTransact(uint32_t code, const Parcel& data,
- Parcel* reply, uint32_t flags = 0);
-
-};
-
-} /* namespace android */
-
-#endif //ANDROID_AAUDIO_IAAUDIO_SERVICE_H
diff --git a/media/libaaudio/src/binding/RingBufferParcelable.cpp b/media/libaaudio/src/binding/RingBufferParcelable.cpp
index 4996b3f..a4b3cec 100644
--- a/media/libaaudio/src/binding/RingBufferParcelable.cpp
+++ b/media/libaaudio/src/binding/RingBufferParcelable.cpp
@@ -29,8 +29,29 @@
using namespace aaudio;
-RingBufferParcelable::RingBufferParcelable() {}
-RingBufferParcelable::~RingBufferParcelable() {}
+RingBufferParcelable::RingBufferParcelable(const RingBuffer& parcelable)
+ : mReadCounterParcelable(std::move(parcelable.readCounterParcelable)),
+ mWriteCounterParcelable(std::move(parcelable.writeCounterParcelable)),
+ mDataParcelable(std::move(parcelable.dataParcelable)),
+ mBytesPerFrame(parcelable.bytesPerFrame),
+ mFramesPerBurst(parcelable.framesPerBurst),
+ mCapacityInFrames(parcelable.capacityInFrames),
+ mFlags(static_cast<RingbufferFlags>(parcelable.flags)) {
+ static_assert(sizeof(mFlags) == sizeof(parcelable.flags));
+}
+
+RingBuffer RingBufferParcelable::parcelable() const {
+ RingBuffer result;
+ result.readCounterParcelable = std::move(mReadCounterParcelable).parcelable();
+ result.writeCounterParcelable = std::move(mWriteCounterParcelable).parcelable();
+ result.dataParcelable = std::move(mDataParcelable).parcelable();
+ result.bytesPerFrame = mBytesPerFrame;
+ result.framesPerBurst = mFramesPerBurst;
+ result.capacityInFrames = mCapacityInFrames;
+ static_assert(sizeof(mFlags) == sizeof(result.flags));
+ result.flags = static_cast<int32_t>(mFlags);
+ return result;
+}
// TODO This assumes that all three use the same SharedMemoryParcelable
void RingBufferParcelable::setupMemory(int32_t sharedMemoryIndex,
@@ -76,58 +97,6 @@
mCapacityInFrames = capacityInFrames;
}
-/**
- * The read and write must be symmetric.
- */
-status_t RingBufferParcelable::writeToParcel(Parcel* parcel) const {
- status_t status = AAudioConvert_aaudioToAndroidStatus(validate());
- if (status != NO_ERROR) goto error;
-
- status = parcel->writeInt32(mCapacityInFrames);
- if (status != NO_ERROR) goto error;
- if (mCapacityInFrames > 0) {
- status = parcel->writeInt32(mBytesPerFrame);
- if (status != NO_ERROR) goto error;
- status = parcel->writeInt32(mFramesPerBurst);
- if (status != NO_ERROR) goto error;
- status = parcel->writeInt32(mFlags);
- if (status != NO_ERROR) goto error;
- status = mReadCounterParcelable.writeToParcel(parcel);
- if (status != NO_ERROR) goto error;
- status = mWriteCounterParcelable.writeToParcel(parcel);
- if (status != NO_ERROR) goto error;
- status = mDataParcelable.writeToParcel(parcel);
- if (status != NO_ERROR) goto error;
- }
- return NO_ERROR;
-error:
- ALOGE("%s returning %d", __func__, status);
- return status;
-}
-
-status_t RingBufferParcelable::readFromParcel(const Parcel* parcel) {
- status_t status = parcel->readInt32(&mCapacityInFrames);
- if (status != NO_ERROR) goto error;
- if (mCapacityInFrames > 0) {
- status = parcel->readInt32(&mBytesPerFrame);
- if (status != NO_ERROR) goto error;
- status = parcel->readInt32(&mFramesPerBurst);
- if (status != NO_ERROR) goto error;
- status = parcel->readInt32((int32_t *)&mFlags);
- if (status != NO_ERROR) goto error;
- status = mReadCounterParcelable.readFromParcel(parcel);
- if (status != NO_ERROR) goto error;
- status = mWriteCounterParcelable.readFromParcel(parcel);
- if (status != NO_ERROR) goto error;
- status = mDataParcelable.readFromParcel(parcel);
- if (status != NO_ERROR) goto error;
- }
- return AAudioConvert_aaudioToAndroidStatus(validate());
-error:
- ALOGE("%s returning %d", __func__, status);
- return status;
-}
-
aaudio_result_t RingBufferParcelable::resolve(SharedMemoryParcelable *memoryParcels, RingBufferDescriptor *descriptor) {
aaudio_result_t result;
diff --git a/media/libaaudio/src/binding/RingBufferParcelable.h b/media/libaaudio/src/binding/RingBufferParcelable.h
index 1dbcf07..2508cea 100644
--- a/media/libaaudio/src/binding/RingBufferParcelable.h
+++ b/media/libaaudio/src/binding/RingBufferParcelable.h
@@ -19,6 +19,7 @@
#include <stdint.h>
+#include <aaudio/RingBuffer.h>
#include <binder/Parcelable.h>
#include "binding/AAudioServiceDefinitions.h"
@@ -26,10 +27,12 @@
namespace aaudio {
-class RingBufferParcelable : public Parcelable {
+class RingBufferParcelable {
public:
- RingBufferParcelable();
- virtual ~RingBufferParcelable();
+ RingBufferParcelable() = default;
+
+ // Construct based on a parcelable representation.
+ explicit RingBufferParcelable(const RingBuffer& parcelable);
// TODO This assumes that all three use the same SharedMemoryParcelable
void setupMemory(int32_t sharedMemoryIndex,
@@ -57,21 +60,14 @@
bool isFileDescriptorSafe(SharedMemoryParcelable *memoryParcels);
- /**
- * The read and write must be symmetric.
- */
- virtual status_t writeToParcel(Parcel* parcel) const override;
-
- virtual status_t readFromParcel(const Parcel* parcel) override;
-
aaudio_result_t resolve(SharedMemoryParcelable *memoryParcels, RingBufferDescriptor *descriptor);
void dump();
+ // Extract a parcelable representation of this object.
+ RingBuffer parcelable() const;
+
private:
-
- aaudio_result_t validate() const;
-
SharedRegionParcelable mReadCounterParcelable;
SharedRegionParcelable mWriteCounterParcelable;
SharedRegionParcelable mDataParcelable;
@@ -79,6 +75,8 @@
int32_t mFramesPerBurst = 0; // for ISOCHRONOUS queues
int32_t mCapacityInFrames = 0; // zero if unused
RingbufferFlags mFlags = RingbufferFlags::NONE;
+
+ aaudio_result_t validate() const;
};
} /* namespace aaudio */
diff --git a/media/libaaudio/src/binding/SharedMemoryParcelable.cpp b/media/libaaudio/src/binding/SharedMemoryParcelable.cpp
index b6e8472..685b779 100644
--- a/media/libaaudio/src/binding/SharedMemoryParcelable.cpp
+++ b/media/libaaudio/src/binding/SharedMemoryParcelable.cpp
@@ -18,6 +18,7 @@
//#define LOG_NDEBUG 0
#include <utils/Log.h>
+#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
@@ -33,61 +34,36 @@
using android::base::unique_fd;
using android::NO_ERROR;
using android::status_t;
-using android::Parcel;
-using android::Parcelable;
+using android::media::SharedFileRegion;
using namespace aaudio;
-SharedMemoryParcelable::SharedMemoryParcelable() {}
-SharedMemoryParcelable::~SharedMemoryParcelable() {};
+SharedMemoryParcelable::SharedMemoryParcelable(SharedFileRegion&& parcelable) {
+ mFd = parcelable.fd.release();
+ mSizeInBytes = parcelable.size;
+ mOffsetInBytes = parcelable.offset;
+}
+
+SharedFileRegion SharedMemoryParcelable::parcelable() && {
+ SharedFileRegion result;
+ result.fd.reset(std::move(mFd));
+ result.size = mSizeInBytes;
+ result.offset = mOffsetInBytes;
+ return result;
+}
+
+SharedMemoryParcelable SharedMemoryParcelable::dup() const {
+ SharedMemoryParcelable result;
+ result.setup(mFd, static_cast<int32_t>(mSizeInBytes));
+ return result;
+}
void SharedMemoryParcelable::setup(const unique_fd& fd, int32_t sizeInBytes) {
- mFd.reset(dup(fd.get())); // store a duplicate fd
+ mFd.reset(::dup(fd.get())); // store a duplicate fd
ALOGV("setup(fd = %d -> %d, size = %d) this = %p\n", fd.get(), mFd.get(), sizeInBytes, this);
mSizeInBytes = sizeInBytes;
}
-status_t SharedMemoryParcelable::writeToParcel(Parcel* parcel) const {
- status_t status = AAudioConvert_aaudioToAndroidStatus(validate());
- if (status != NO_ERROR) return status;
-
- status = parcel->writeInt32(mSizeInBytes);
- if (status != NO_ERROR) return status;
- if (mSizeInBytes > 0) {
- ALOGV("writeToParcel() mFd = %d, this = %p\n", mFd.get(), this);
- status = parcel->writeUniqueFileDescriptor(mFd);
- ALOGE_IF(status != NO_ERROR, "SharedMemoryParcelable writeDupFileDescriptor failed : %d",
- status);
- }
- return status;
-}
-
-status_t SharedMemoryParcelable::readFromParcel(const Parcel* parcel) {
- status_t status = parcel->readInt32(&mSizeInBytes);
- if (status != NO_ERROR) goto error;
-
- if (mSizeInBytes > 0) {
- // The Parcel owns the file descriptor and will close it later.
- unique_fd mmapFd;
- status = parcel->readUniqueFileDescriptor(&mmapFd);
- if (status != NO_ERROR) {
- ALOGE("readFromParcel() readUniqueFileDescriptor() failed : %d", status);
- goto error;
- }
-
- // Resolve the memory now while we still have the FD from the Parcel.
- // Closing the FD will not affect the shared memory once mmap() has been called.
- aaudio_result_t result = resolveSharedMemory(mmapFd);
- status = AAudioConvert_aaudioToAndroidStatus(result);
- if (status != NO_ERROR) goto error;
- }
-
- return AAudioConvert_aaudioToAndroidStatus(validate());
-
-error:
- return status;
-}
-
aaudio_result_t SharedMemoryParcelable::close() {
if (mResolvedAddress != MMAP_UNRESOLVED_ADDRESS) {
int err = munmap(mResolvedAddress, mSizeInBytes);
@@ -104,7 +80,7 @@
mResolvedAddress = (uint8_t *) mmap(0, mSizeInBytes, PROT_READ | PROT_WRITE,
MAP_SHARED, fd.get(), 0);
if (mResolvedAddress == MMAP_UNRESOLVED_ADDRESS) {
- ALOGE("mmap() failed for fd = %d, nBytes = %d, errno = %s",
+ ALOGE("mmap() failed for fd = %d, nBytes = %" PRId64 ", errno = %s",
fd.get(), mSizeInBytes, strerror(errno));
return AAUDIO_ERROR_INTERNAL;
}
@@ -118,7 +94,7 @@
return AAUDIO_ERROR_OUT_OF_RANGE;
} else if ((offsetInBytes + sizeInBytes) > mSizeInBytes) {
ALOGE("out of range, offsetInBytes = %d, "
- "sizeInBytes = %d, mSizeInBytes = %d",
+ "sizeInBytes = %d, mSizeInBytes = %" PRId64,
offsetInBytes, sizeInBytes, mSizeInBytes);
return AAUDIO_ERROR_OUT_OF_RANGE;
}
@@ -148,7 +124,11 @@
aaudio_result_t SharedMemoryParcelable::validate() const {
if (mSizeInBytes < 0 || mSizeInBytes >= MAX_MMAP_SIZE_BYTES) {
- ALOGE("invalid mSizeInBytes = %d", mSizeInBytes);
+ ALOGE("invalid mSizeInBytes = %" PRId64, mSizeInBytes);
+ return AAUDIO_ERROR_OUT_OF_RANGE;
+ }
+ if (mOffsetInBytes != 0) {
+ ALOGE("invalid mOffsetInBytes = %" PRId64, mOffsetInBytes);
return AAUDIO_ERROR_OUT_OF_RANGE;
}
return AAUDIO_OK;
@@ -156,5 +136,5 @@
void SharedMemoryParcelable::dump() {
ALOGD("mFd = %d", mFd.get());
- ALOGD("mSizeInBytes = %d", mSizeInBytes);
+ ALOGD("mSizeInBytes = %" PRId64, mSizeInBytes);
}
diff --git a/media/libaaudio/src/binding/SharedMemoryParcelable.h b/media/libaaudio/src/binding/SharedMemoryParcelable.h
index 3927f58..1f2c335 100644
--- a/media/libaaudio/src/binding/SharedMemoryParcelable.h
+++ b/media/libaaudio/src/binding/SharedMemoryParcelable.h
@@ -21,8 +21,7 @@
#include <sys/mman.h>
#include <android-base/unique_fd.h>
-#include <binder/Parcel.h>
-#include <binder/Parcelable.h>
+#include <android/media/SharedFileRegion.h>
namespace aaudio {
@@ -36,10 +35,14 @@
* It may be divided into several regions.
* The memory can be shared using Binder or simply shared between threads.
*/
-class SharedMemoryParcelable : public android::Parcelable {
+class SharedMemoryParcelable {
public:
- SharedMemoryParcelable();
- virtual ~SharedMemoryParcelable();
+ SharedMemoryParcelable() = default;
+
+ // Ctor from a parcelable representation.
+ // Since the parcelable object owns a unique FD, move semantics are provided to avoid the need
+ // to dupe.
+ explicit SharedMemoryParcelable(android::media::SharedFileRegion&& parcelable);
/**
* Make a dup() of the fd and store it for later use.
@@ -49,10 +52,6 @@
*/
void setup(const android::base::unique_fd& fd, int32_t sizeInBytes);
- virtual android::status_t writeToParcel(android::Parcel* parcel) const override;
-
- virtual android::status_t readFromParcel(const android::Parcel* parcel) override;
-
// mmap() shared memory
aaudio_result_t resolve(int32_t offsetInBytes, int32_t sizeInBytes, void **regionAddressPtr);
@@ -63,20 +62,23 @@
void dump();
-protected:
+ // Extract a parcelable representation of this object.
+ // Since we own a unique FD, move semantics are provided to avoid the need to dupe.
+ android::media::SharedFileRegion parcelable() &&;
-#define MMAP_UNRESOLVED_ADDRESS reinterpret_cast<uint8_t*>(MAP_FAILED)
-
- aaudio_result_t resolveSharedMemory(const android::base::unique_fd& fd);
-
- android::base::unique_fd mFd;
- int32_t mSizeInBytes = 0;
- uint8_t *mResolvedAddress = MMAP_UNRESOLVED_ADDRESS;
+ // Copy this instance. Duplicates the underlying FD.
+ SharedMemoryParcelable dup() const;
private:
+#define MMAP_UNRESOLVED_ADDRESS reinterpret_cast<uint8_t*>(MAP_FAILED)
+ android::base::unique_fd mFd;
+ int64_t mSizeInBytes = 0;
+ int64_t mOffsetInBytes = 0;
+ uint8_t *mResolvedAddress = MMAP_UNRESOLVED_ADDRESS;
+
+ aaudio_result_t resolveSharedMemory(const android::base::unique_fd& fd);
aaudio_result_t validate() const;
-
};
} /* namespace aaudio */
diff --git a/media/libaaudio/src/binding/SharedRegionParcelable.cpp b/media/libaaudio/src/binding/SharedRegionParcelable.cpp
index c776116..56b99c0 100644
--- a/media/libaaudio/src/binding/SharedRegionParcelable.cpp
+++ b/media/libaaudio/src/binding/SharedRegionParcelable.cpp
@@ -36,8 +36,18 @@
using namespace aaudio;
-SharedRegionParcelable::SharedRegionParcelable() {}
-SharedRegionParcelable::~SharedRegionParcelable() {}
+SharedRegionParcelable::SharedRegionParcelable(const SharedRegion& parcelable)
+ : mSharedMemoryIndex(parcelable.sharedMemoryIndex),
+ mOffsetInBytes(parcelable.offsetInBytes),
+ mSizeInBytes(parcelable.sizeInBytes) {}
+
+SharedRegion SharedRegionParcelable::parcelable() const {
+ SharedRegion result;
+ result.sharedMemoryIndex = mSharedMemoryIndex;
+ result.offsetInBytes = mOffsetInBytes;
+ result.sizeInBytes = mSizeInBytes;
+ return result;
+}
void SharedRegionParcelable::setup(int32_t sharedMemoryIndex,
int32_t offsetInBytes,
@@ -47,41 +57,6 @@
mSizeInBytes = sizeInBytes;
}
-status_t SharedRegionParcelable::writeToParcel(Parcel* parcel) const {
- status_t status = AAudioConvert_aaudioToAndroidStatus(validate());
- if (status != NO_ERROR) goto error;
-
- status = parcel->writeInt32(mSizeInBytes);
- if (status != NO_ERROR) goto error;
- if (mSizeInBytes > 0) {
- status = parcel->writeInt32(mSharedMemoryIndex);
- if (status != NO_ERROR) goto error;
- status = parcel->writeInt32(mOffsetInBytes);
- if (status != NO_ERROR) goto error;
- }
- return NO_ERROR;
-
-error:
- ALOGE("%s returning %d", __func__, status);
- return status;
-}
-
-status_t SharedRegionParcelable::readFromParcel(const Parcel* parcel) {
- status_t status = parcel->readInt32(&mSizeInBytes);
- if (status != NO_ERROR) goto error;
- if (mSizeInBytes > 0) {
- status = parcel->readInt32(&mSharedMemoryIndex);
- if (status != NO_ERROR) goto error;
- status = parcel->readInt32(&mOffsetInBytes);
- if (status != NO_ERROR) goto error;
- }
- return AAudioConvert_aaudioToAndroidStatus(validate());
-
-error:
- ALOGE("%s returning %d", __func__, status);
- return status;
-}
-
aaudio_result_t SharedRegionParcelable::resolve(SharedMemoryParcelable *memoryParcels,
void **regionAddressPtr) {
if (mSizeInBytes == 0) {
diff --git a/media/libaaudio/src/binding/SharedRegionParcelable.h b/media/libaaudio/src/binding/SharedRegionParcelable.h
index 0cd8c04..c15fc30 100644
--- a/media/libaaudio/src/binding/SharedRegionParcelable.h
+++ b/media/libaaudio/src/binding/SharedRegionParcelable.h
@@ -20,41 +20,39 @@
#include <stdint.h>
#include <sys/mman.h>
-#include <binder/Parcelable.h>
#include <aaudio/AAudio.h>
+#include <aaudio/SharedRegion.h>
#include "binding/SharedMemoryParcelable.h"
using android::status_t;
-using android::Parcel;
-using android::Parcelable;
namespace aaudio {
-class SharedRegionParcelable : public Parcelable {
+class SharedRegionParcelable {
public:
- SharedRegionParcelable();
- virtual ~SharedRegionParcelable();
+ SharedRegionParcelable() = default;
+
+ // Construct based on a parcelable representation.
+ explicit SharedRegionParcelable(const SharedRegion& parcelable);
void setup(int32_t sharedMemoryIndex, int32_t offsetInBytes, int32_t sizeInBytes);
- virtual status_t writeToParcel(Parcel* parcel) const override;
-
- virtual status_t readFromParcel(const Parcel* parcel) override;
-
aaudio_result_t resolve(SharedMemoryParcelable *memoryParcels, void **regionAddressPtr);
bool isFileDescriptorSafe(SharedMemoryParcelable *memoryParcels);
void dump();
-protected:
+ // Extract a parcelable representation of this object.
+ SharedRegion parcelable() const;
+
+private:
int32_t mSharedMemoryIndex = -1;
int32_t mOffsetInBytes = 0;
int32_t mSizeInBytes = 0;
-private:
aaudio_result_t validate() const;
};
diff --git a/media/libaaudio/src/binding/aidl/aaudio/Endpoint.aidl b/media/libaaudio/src/binding/aidl/aaudio/Endpoint.aidl
new file mode 100644
index 0000000..3600b6a
--- /dev/null
+++ b/media/libaaudio/src/binding/aidl/aaudio/Endpoint.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package aaudio;
+
+import aaudio.RingBuffer;
+import android.media.SharedFileRegion;
+
+parcelable Endpoint {
+ // Set capacityInFrames to zero if Queue is unused.
+ RingBuffer upMessageQueueParcelable; // server to client
+ RingBuffer downMessageQueueParcelable; // to server
+ RingBuffer upDataQueueParcelable; // eg. record, could share same queue
+ RingBuffer downDataQueueParcelable; // eg. playback
+ SharedFileRegion[] sharedMemories;
+}
diff --git a/media/libaaudio/src/binding/aidl/aaudio/IAAudioService.aidl b/media/libaaudio/src/binding/aidl/aaudio/IAAudioService.aidl
new file mode 100644
index 0000000..44d2211
--- /dev/null
+++ b/media/libaaudio/src/binding/aidl/aaudio/IAAudioService.aidl
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package aaudio;
+
+import aaudio.Endpoint;
+import aaudio.IAAudioClient;
+import aaudio.StreamParameters;
+import aaudio.StreamRequest;
+
+interface IAAudioService {
+ /**
+ * Register an object to receive audio input/output change and track notifications.
+ * For a given calling pid, AAudio service disregards any registrations after the first.
+ * Thus the IAAudioClient must be a singleton per process.
+ */
+ void registerClient(IAAudioClient client);
+
+ /**
+ * @param request info needed to create the stream
+ * @param paramsOut contains information about the created stream
+ * @return handle to the stream or a negative error
+ */
+ int openStream(in StreamRequest request,
+ out StreamParameters paramsOut);
+
+ int closeStream(int streamHandle);
+
+ /*
+ * Get an immutable description of the in-memory queues
+ * used to communicate with the underlying HAL or Service.
+ */
+ int getStreamDescription(int streamHandle, out Endpoint endpoint);
+
+ /**
+ * Start the flow of data.
+ * This is asynchronous. When complete, the service will send a STARTED event.
+ */
+ int startStream(int streamHandle);
+
+ /**
+ * 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.
+ */
+ int pauseStream(int streamHandle);
+
+ /**
+ * Stop the flow of data such that the data currently in the buffer is played.
+ * This is asynchronous. When complete, the service will send a STOPPED event.
+ */
+ int stopStream(int streamHandle);
+
+ /**
+ * Discard any data held by the underlying HAL or Service.
+ * This is asynchronous. When complete, the service will send a FLUSHED event.
+ */
+ int flushStream(int streamHandle);
+
+ /**
+ * Manage the specified thread as a low latency audio thread.
+ */
+ int registerAudioThread(int streamHandle,
+ int clientThreadId,
+ long periodNanoseconds);
+
+ int unregisterAudioThread(int streamHandle,
+ int clientThreadId);
+}
diff --git a/media/libaaudio/src/binding/aidl/aaudio/RingBuffer.aidl b/media/libaaudio/src/binding/aidl/aaudio/RingBuffer.aidl
new file mode 100644
index 0000000..a58b33a
--- /dev/null
+++ b/media/libaaudio/src/binding/aidl/aaudio/RingBuffer.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package aaudio;
+
+import aaudio.SharedRegion;
+
+parcelable RingBuffer {
+ SharedRegion readCounterParcelable;
+ SharedRegion writeCounterParcelable;
+ SharedRegion dataParcelable;
+ int bytesPerFrame; // index is in frames
+ int framesPerBurst; // for ISOCHRONOUS queues
+ int capacityInFrames; // zero if unused
+ int /* RingbufferFlags */ flags; // = RingbufferFlags::NONE;
+}
\ No newline at end of file
diff --git a/media/libaaudio/src/binding/aidl/aaudio/SharedRegion.aidl b/media/libaaudio/src/binding/aidl/aaudio/SharedRegion.aidl
new file mode 100644
index 0000000..26153e8
--- /dev/null
+++ b/media/libaaudio/src/binding/aidl/aaudio/SharedRegion.aidl
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package aaudio;
+
+parcelable SharedRegion {
+ int sharedMemoryIndex;
+ int offsetInBytes;
+ int sizeInBytes;
+}
diff --git a/media/libaaudio/src/binding/aidl/aaudio/StreamParameters.aidl b/media/libaaudio/src/binding/aidl/aaudio/StreamParameters.aidl
new file mode 100644
index 0000000..b7c4f70
--- /dev/null
+++ b/media/libaaudio/src/binding/aidl/aaudio/StreamParameters.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package aaudio;
+
+import android.media.audio.common.AudioFormat;
+
+parcelable StreamParameters {
+ int samplesPerFrame; // = AAUDIO_UNSPECIFIED;
+ int sampleRate; // = AAUDIO_UNSPECIFIED;
+ int deviceId; // = AAUDIO_UNSPECIFIED;
+ int /* aaudio_sharing_mode_t */ sharingMode; // = AAUDIO_SHARING_MODE_SHARED;
+ AudioFormat audioFormat; // = AUDIO_FORMAT_DEFAULT;
+ int /* aaudio_direction_t */ direction; // = AAUDIO_DIRECTION_OUTPUT;
+ int /* aaudio_usage_t */ usage; // = AAUDIO_UNSPECIFIED;
+ int /* aaudio_content_type_t */ contentType; // = AAUDIO_UNSPECIFIED;
+ int /* aaudio_input_preset_t */ inputPreset; // = AAUDIO_UNSPECIFIED;
+ int bufferCapacity; // = AAUDIO_UNSPECIFIED;
+ int /* aaudio_allowed_capture_policy_t */ allowedCapturePolicy; // = AAUDIO_UNSPECIFIED;
+ int /* aaudio_session_id_t */ sessionId; // = AAUDIO_SESSION_ID_NONE;
+ boolean isPrivacySensitive; // = false;
+}
diff --git a/media/libaaudio/src/binding/aidl/aaudio/StreamRequest.aidl b/media/libaaudio/src/binding/aidl/aaudio/StreamRequest.aidl
new file mode 100644
index 0000000..9bf4077
--- /dev/null
+++ b/media/libaaudio/src/binding/aidl/aaudio/StreamRequest.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package aaudio;
+
+import aaudio.StreamParameters;
+
+parcelable StreamRequest {
+ StreamParameters params;
+ int userId; // = (uid_t) -1;
+ int processId; // = (pid_t) -1;
+ boolean sharingModeMatchRequired; // = false;
+ boolean inService; // = false; // Stream opened by AAudioservice
+}
\ No newline at end of file
diff --git a/media/libaaudio/src/client/AudioStreamInternal.cpp b/media/libaaudio/src/client/AudioStreamInternal.cpp
index ac7ad9a..2688597 100644
--- a/media/libaaudio/src/client/AudioStreamInternal.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternal.cpp
@@ -34,7 +34,6 @@
#include "AudioEndpointParcelable.h"
#include "binding/AAudioStreamRequest.h"
#include "binding/AAudioStreamConfiguration.h"
-#include "binding/IAAudioService.h"
#include "binding/AAudioServiceMessage.h"
#include "core/AudioGlobal.h"
#include "core/AudioStreamBuilder.h"
diff --git a/media/libaaudio/src/client/AudioStreamInternal.h b/media/libaaudio/src/client/AudioStreamInternal.h
index 63be978..162f098 100644
--- a/media/libaaudio/src/client/AudioStreamInternal.h
+++ b/media/libaaudio/src/client/AudioStreamInternal.h
@@ -20,7 +20,6 @@
#include <stdint.h>
#include <aaudio/AAudio.h>
-#include "binding/IAAudioService.h"
#include "binding/AudioEndpointParcelable.h"
#include "binding/AAudioServiceInterface.h"
#include "client/IsochronousClockModel.h"
@@ -29,7 +28,6 @@
#include "utility/AudioClock.h"
using android::sp;
-using android::IAAudioService;
namespace aaudio {
diff --git a/media/libaaudio/src/client/AudioStreamInternalCapture.h b/media/libaaudio/src/client/AudioStreamInternalCapture.h
index 1d65d87..251a7f2 100644
--- a/media/libaaudio/src/client/AudioStreamInternalCapture.h
+++ b/media/libaaudio/src/client/AudioStreamInternalCapture.h
@@ -23,7 +23,6 @@
#include "client/AudioStreamInternal.h"
using android::sp;
-using android::IAAudioService;
namespace aaudio {
diff --git a/media/libaaudio/src/client/AudioStreamInternalPlay.cpp b/media/libaaudio/src/client/AudioStreamInternalPlay.cpp
index b47b472..980592c 100644
--- a/media/libaaudio/src/client/AudioStreamInternalPlay.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternalPlay.cpp
@@ -32,6 +32,7 @@
#define LOG_TAG (mInService ? "AudioStreamInternalPlay_Service" \
: "AudioStreamInternalPlay_Client")
+using android::status_t;
using android::WrappingBuffer;
using namespace aaudio;
diff --git a/media/libaaudio/src/client/AudioStreamInternalPlay.h b/media/libaaudio/src/client/AudioStreamInternalPlay.h
index be95da6..7b1cddc 100644
--- a/media/libaaudio/src/client/AudioStreamInternalPlay.h
+++ b/media/libaaudio/src/client/AudioStreamInternalPlay.h
@@ -25,7 +25,6 @@
#include "client/AudioStreamInternal.h"
using android::sp;
-using android::IAAudioService;
namespace aaudio {
diff --git a/media/libaaudio/tests/Android.bp b/media/libaaudio/tests/Android.bp
index 8935d57..95d6543 100644
--- a/media/libaaudio/tests/Android.bp
+++ b/media/libaaudio/tests/Android.bp
@@ -11,10 +11,12 @@
defaults: ["libaaudio_tests_defaults"],
srcs: ["test_marshalling.cpp"],
shared_libs: [
+ "aaudio-aidl-cpp",
"libaaudio_internal",
"libbinder",
"libcutils",
"libutils",
+ "shared-file-region-aidl-unstable-cpp",
],
}
diff --git a/media/libaaudio/tests/test_marshalling.cpp b/media/libaaudio/tests/test_marshalling.cpp
index c51fbce..49213dc 100644
--- a/media/libaaudio/tests/test_marshalling.cpp
+++ b/media/libaaudio/tests/test_marshalling.cpp
@@ -33,6 +33,29 @@
using namespace android;
using namespace aaudio;
+template<typename T>
+T copy(const T& object) {
+ return T(object);
+}
+
+template<>
+SharedMemoryParcelable copy<SharedMemoryParcelable>(const SharedMemoryParcelable& object) {
+ return object.dup();
+}
+
+template<typename T>
+void writeToParcel(const T& object, Parcel* parcel) {
+ copy(object).parcelable().writeToParcel(parcel);
+}
+
+template<typename T>
+T readFromParcel(const Parcel& parcel) {
+ using ParcelType = std::decay_t<decltype(std::declval<T>().parcelable())>;
+ ParcelType parcelable;
+ parcelable.readFromParcel(&parcel);
+ return T(std::move(parcelable));
+}
+
// Test adding one value.
TEST(test_marshalling, aaudio_one_read_write) {
Parcel parcel;
@@ -48,7 +71,6 @@
// Test SharedMemoryParcel.
TEST(test_marshalling, aaudio_shared_memory) {
SharedMemoryParcelable sharedMemoryA;
- SharedMemoryParcelable sharedMemoryB;
const size_t memSizeBytes = 840;
unique_fd fd(ashmem_create_region("TestMarshalling", memSizeBytes));
ASSERT_LE(0, fd);
@@ -63,10 +85,10 @@
Parcel parcel;
size_t pos = parcel.dataPosition();
- sharedMemoryA.writeToParcel(&parcel);
+ writeToParcel(sharedMemoryA, &parcel);
parcel.setDataPosition(pos);
- sharedMemoryB.readFromParcel(&parcel);
+ SharedMemoryParcelable sharedMemoryB = readFromParcel<SharedMemoryParcelable>(parcel);
EXPECT_EQ(sharedMemoryA.getSizeInBytes(), sharedMemoryB.getSizeInBytes());
// should see same value at two different addresses
@@ -81,7 +103,6 @@
TEST(test_marshalling, aaudio_shared_region) {
SharedMemoryParcelable sharedMemories[2];
SharedRegionParcelable sharedRegionA;
- SharedRegionParcelable sharedRegionB;
const size_t memSizeBytes = 840;
unique_fd fd(ashmem_create_region("TestMarshalling", memSizeBytes));
ASSERT_LE(0, fd);
@@ -97,10 +118,10 @@
Parcel parcel;
size_t pos = parcel.dataPosition();
- sharedRegionA.writeToParcel(&parcel);
+ writeToParcel(sharedRegionA, &parcel);
parcel.setDataPosition(pos);
- sharedRegionB.readFromParcel(&parcel);
+ SharedRegionParcelable sharedRegionB = readFromParcel<SharedRegionParcelable>(parcel);
// should see same value
void *region2;
@@ -113,7 +134,6 @@
TEST(test_marshalling, aaudio_ring_buffer_parcelable) {
SharedMemoryParcelable sharedMemories[2];
RingBufferParcelable ringBufferA;
- RingBufferParcelable ringBufferB;
const size_t bytesPerFrame = 8;
const size_t framesPerBurst = 32;
@@ -147,11 +167,11 @@
// write A to parcel
Parcel parcel;
size_t pos = parcel.dataPosition();
- ringBufferA.writeToParcel(&parcel);
+ writeToParcel(ringBufferA, &parcel);
// read B from parcel
parcel.setDataPosition(pos);
- ringBufferB.readFromParcel(&parcel);
+ RingBufferParcelable ringBufferB = readFromParcel<RingBufferParcelable>(parcel);
RingBufferDescriptor descriptorB;
EXPECT_EQ(AAUDIO_OK, ringBufferB.resolve(sharedMemories, &descriptorB));