Convert IEffect and IEffectClient to AIDL
This change replaces the manually-parceled IEffect and IEffectClient
with AIDL definitions.
In addition, this includes a small library that facilitates shared
memory regions over AIDL.
Bug: 160253486
Test: Ran effects-related CTS tests. Manual verification of basic
audio functionality on Sargo.
Change-Id: I5a9c5f2f24c10072ad5067acc71aa30581af41c1
diff --git a/media/libaudioclient/Android.bp b/media/libaudioclient/Android.bp
index e8e1a09..2a1e56c 100644
--- a/media/libaudioclient/Android.bp
+++ b/media/libaudioclient/Android.bp
@@ -77,8 +77,6 @@
"IAudioPolicyService.cpp",
"IAudioPolicyServiceClient.cpp",
"IAudioTrack.cpp",
- "IEffect.cpp",
- "IEffectClient.cpp",
"ToneGenerator.cpp",
"PlayerBase.cpp",
"RecordingActivityTracker.cpp",
@@ -99,6 +97,7 @@
"libmediautils",
"libnblog",
"libprocessgroup",
+ "libshmemcompat",
"libutils",
"libvibrator",
],
@@ -108,7 +107,8 @@
"frameworks/av/media/libnbaio/include_mono/",
],
local_include_dirs: [
- "include/media", "aidl"
+ "include/media",
+ "aidl",
],
header_libs: [
"libaudioclient_headers",
@@ -116,10 +116,16 @@
"libmedia_headers",
],
export_header_lib_headers: ["libaudioclient_headers"],
+ export_static_lib_headers: [
+ "effect-aidl-cpp",
+ "shared-file-region-aidl-cpp",
+ ],
- // for memory heap analysis
static_libs: [
+ "effect-aidl-cpp",
+ // for memory heap analysis
"libc_malloc_debug_backtrace",
+ "shared-file-region-aidl-cpp",
],
cflags: [
"-Wall",
@@ -127,7 +133,7 @@
"-Wno-error=deprecated-declarations",
],
sanitize: {
- misc_undefined : [
+ misc_undefined: [
"unsigned-integer-overflow",
"signed-integer-overflow",
],
@@ -170,3 +176,16 @@
"aidl/android/media/ICaptureStateListener.aidl",
],
}
+
+aidl_interface {
+ name: "effect-aidl",
+ unstable: true,
+ local_include_dir: "aidl",
+ srcs: [
+ "aidl/android/media/IEffect.aidl",
+ "aidl/android/media/IEffectClient.aidl",
+ ],
+ imports: [
+ "shared-file-region-aidl",
+ ],
+}
diff --git a/media/libaudioclient/AudioEffect.cpp b/media/libaudioclient/AudioEffect.cpp
index 73b96ab..1282474 100644
--- a/media/libaudioclient/AudioEffect.cpp
+++ b/media/libaudioclient/AudioEffect.cpp
@@ -23,16 +23,28 @@
#include <sys/types.h>
#include <limits.h>
-#include <private/media/AudioEffectShared.h>
-#include <media/AudioEffect.h>
-
-#include <utils/Log.h>
#include <binder/IPCThreadState.h>
-
-
+#include <media/AudioEffect.h>
+#include <media/ShmemCompat.h>
+#include <private/media/AudioEffectShared.h>
+#include <utils/Log.h>
namespace android {
+using binder::Status;
+
+namespace {
+
+// Copy from a raw pointer + size into a vector of bytes.
+void appendToBuffer(const void* data,
+ size_t size,
+ std::vector<uint8_t>* buffer) {
+ const uint8_t* p = reinterpret_cast<const uint8_t*>(data);
+ buffer->insert(buffer->end(), p, p + size);
+}
+
+} // namespace
+
// ---------------------------------------------------------------------------
AudioEffect::AudioEffect(const String16& opPackageName)
@@ -50,7 +62,7 @@
const AudioDeviceTypeAddr& device,
bool probe)
{
- sp<IEffect> iEffect;
+ sp<media::IEffect> iEffect;
sp<IMemory> cblk;
int enabled;
@@ -112,8 +124,10 @@
mEnabled = (volatile int32_t)enabled;
- cblk = iEffect->getCblk();
- if (cblk == 0) {
+ if (media::SharedFileRegion shmem;
+ !iEffect->getCblk(&shmem).isOk()
+ || !convertSharedFileRegionToIMemory(shmem, &cblk)
+ || cblk == 0) {
mStatus = NO_INIT;
ALOGE("Could not get control block");
return mStatus;
@@ -216,15 +230,19 @@
}
status_t status = NO_ERROR;
-
AutoMutex lock(mLock);
if (enabled != mEnabled) {
+ Status bs;
+
if (enabled) {
ALOGV("enable %p", this);
- status = mIEffect->enable();
+ bs = mIEffect->enable(&status);
} else {
ALOGV("disable %p", this);
- status = mIEffect->disable();
+ bs = mIEffect->disable(&status);
+ }
+ if (!bs.isOk()) {
+ status = bs.transactionError();
}
if (status == NO_ERROR) {
mEnabled = enabled;
@@ -257,7 +275,20 @@
mLock.lock();
}
- status_t status = mIEffect->command(cmdCode, cmdSize, cmdData, replySize, replyData);
+ std::vector<uint8_t> data;
+ appendToBuffer(cmdData, cmdSize, &data);
+
+ status_t status;
+ std::vector<uint8_t> response;
+
+ Status bs = mIEffect->command(cmdCode, data, *replySize, &response, &status);
+ if (!bs.isOk()) {
+ status = bs.transactionError();
+ }
+ if (status == NO_ERROR) {
+ memcpy(replyData, response.data(), response.size());
+ *replySize = response.size();
+ }
if (cmdCode == EFFECT_CMD_ENABLE || cmdCode == EFFECT_CMD_DISABLE) {
if (status == NO_ERROR) {
@@ -272,7 +303,6 @@
return status;
}
-
status_t AudioEffect::setParameter(effect_param_t *param)
{
if (mProbe) {
@@ -286,14 +316,27 @@
return BAD_VALUE;
}
- uint32_t size = sizeof(int);
uint32_t psize = ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) + param->vsize;
ALOGV("setParameter: param: %d, param2: %d", *(int *)param->data,
(param->psize == 8) ? *((int *)param->data + 1): -1);
- return mIEffect->command(EFFECT_CMD_SET_PARAM, sizeof (effect_param_t) + psize, param, &size,
- ¶m->status);
+ std::vector<uint8_t> cmd;
+ appendToBuffer(param, sizeof(effect_param_t) + psize, &cmd);
+ std::vector<uint8_t> response;
+ status_t status;
+ Status bs = mIEffect->command(EFFECT_CMD_SET_PARAM,
+ cmd,
+ sizeof(int),
+ &response,
+ &status);
+ if (!bs.isOk()) {
+ status = bs.transactionError();
+ return status;
+ }
+ assert(response.size() == sizeof(int));
+ memcpy(¶m->status, response.data(), response.size());
+ return status;
}
status_t AudioEffect::setParameterDeferred(effect_param_t *param)
@@ -338,8 +381,18 @@
if (mCblk->clientIndex == 0) {
return INVALID_OPERATION;
}
- uint32_t size = 0;
- return mIEffect->command(EFFECT_CMD_SET_PARAM_COMMIT, 0, NULL, &size, NULL);
+ std::vector<uint8_t> cmd;
+ std::vector<uint8_t> response;
+ status_t status;
+ Status bs = mIEffect->command(EFFECT_CMD_SET_PARAM_COMMIT,
+ cmd,
+ 0,
+ &response,
+ &status);
+ if (!bs.isOk()) {
+ status = bs.transactionError();
+ }
+ return status;
}
status_t AudioEffect::getParameter(effect_param_t *param)
@@ -361,8 +414,18 @@
uint32_t psize = sizeof(effect_param_t) + ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) +
param->vsize;
- return mIEffect->command(EFFECT_CMD_GET_PARAM, sizeof(effect_param_t) + param->psize, param,
- &psize, param);
+ status_t status;
+ std::vector<uint8_t> cmd;
+ std::vector<uint8_t> response;
+ appendToBuffer(param, sizeof(effect_param_t) + param->psize, &cmd);
+
+ Status bs = mIEffect->command(EFFECT_CMD_GET_PARAM, cmd, psize, &response, &status);
+ if (!bs.isOk()) {
+ status = bs.transactionError();
+ return status;
+ }
+ memcpy(param, response.data(), response.size());
+ return status;
}
@@ -410,19 +473,18 @@
}
}
-void AudioEffect::commandExecuted(uint32_t cmdCode,
- uint32_t cmdSize __unused,
- void *cmdData,
- uint32_t replySize __unused,
- void *replyData)
+void AudioEffect::commandExecuted(int32_t cmdCode,
+ const std::vector<uint8_t>& cmdData,
+ const std::vector<uint8_t>& replyData)
{
- if (cmdData == NULL || replyData == NULL) {
+ if (cmdData.empty() || replyData.empty()) {
return;
}
if (mCbf != NULL && cmdCode == EFFECT_CMD_SET_PARAM) {
- effect_param_t *cmd = (effect_param_t *)cmdData;
- cmd->status = *(int32_t *)replyData;
+ std::vector<uint8_t> cmdDataCopy(cmdData);
+ effect_param_t* cmd = reinterpret_cast<effect_param_t *>(cmdDataCopy.data());
+ cmd->status = *reinterpret_cast<const int32_t *>(replyData.data());
mCbf(EVENT_PARAMETER_CHANGED, mUserData, cmd);
}
}
diff --git a/media/libaudioclient/IAudioFlinger.cpp b/media/libaudioclient/IAudioFlinger.cpp
index 6d79aba..225713a 100644
--- a/media/libaudioclient/IAudioFlinger.cpp
+++ b/media/libaudioclient/IAudioFlinger.cpp
@@ -653,9 +653,9 @@
return NO_ERROR;
}
- virtual sp<IEffect> createEffect(
+ virtual sp<media::IEffect> createEffect(
effect_descriptor_t *pDesc,
- const sp<IEffectClient>& client,
+ const sp<media::IEffectClient>& client,
int32_t priority,
audio_io_handle_t output,
audio_session_t sessionId,
@@ -668,7 +668,7 @@
int *enabled)
{
Parcel data, reply;
- sp<IEffect> effect;
+ sp<media::IEffect> effect;
if (pDesc == NULL) {
if (status != NULL) {
*status = BAD_VALUE;
@@ -705,7 +705,7 @@
if (enabled != NULL) {
*enabled = tmp;
}
- effect = interface_cast<IEffect>(reply.readStrongBinder());
+ effect = interface_cast<media::IEffect>(reply.readStrongBinder());
reply.read(pDesc, sizeof(effect_descriptor_t));
}
if (status != NULL) {
@@ -1386,7 +1386,8 @@
if (data.read(&desc, sizeof(effect_descriptor_t)) != NO_ERROR) {
ALOGE("b/23905951");
}
- sp<IEffectClient> client = interface_cast<IEffectClient>(data.readStrongBinder());
+ sp<media::IEffectClient> client =
+ interface_cast<media::IEffectClient>(data.readStrongBinder());
int32_t priority = data.readInt32();
audio_io_handle_t output = (audio_io_handle_t) data.readInt32();
audio_session_t sessionId = (audio_session_t) data.readInt32();
@@ -1402,8 +1403,8 @@
int id = 0;
int enabled = 0;
- sp<IEffect> effect = createEffect(&desc, client, priority, output, sessionId, device,
- opPackageName, pid, probe, &status, &id, &enabled);
+ sp<media::IEffect> effect = createEffect(&desc, client, priority, output, sessionId,
+ device, opPackageName, pid, probe, &status, &id, &enabled);
reply->writeInt32(status);
reply->writeInt32(id);
reply->writeInt32(enabled);
diff --git a/media/libaudioclient/IEffect.cpp b/media/libaudioclient/IEffect.cpp
deleted file mode 100644
index 5d47dff..0000000
--- a/media/libaudioclient/IEffect.cpp
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
-**
-** Copyright 2010, 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_NDEBUG 0
-#define LOG_TAG "IEffect"
-#include <utils/Log.h>
-#include <stdint.h>
-#include <sys/types.h>
-#include <binder/Parcel.h>
-#include <media/IEffect.h>
-
-namespace android {
-
-// Maximum command/reply size expected
-#define EFFECT_PARAM_SIZE_MAX 65536
-
-enum {
- ENABLE = IBinder::FIRST_CALL_TRANSACTION,
- DISABLE,
- COMMAND,
- DISCONNECT,
- GET_CBLK
-};
-
-class BpEffect: public BpInterface<IEffect>
-{
-public:
- explicit BpEffect(const sp<IBinder>& impl)
- : BpInterface<IEffect>(impl)
- {
- }
-
- status_t enable()
- {
- ALOGV("enable");
- Parcel data, reply;
- data.writeInterfaceToken(IEffect::getInterfaceDescriptor());
- remote()->transact(ENABLE, data, &reply);
- return reply.readInt32();
- }
-
- status_t disable()
- {
- ALOGV("disable");
- Parcel data, reply;
- data.writeInterfaceToken(IEffect::getInterfaceDescriptor());
- remote()->transact(DISABLE, data, &reply);
- return reply.readInt32();
- }
-
- status_t command(uint32_t cmdCode,
- uint32_t cmdSize,
- void *pCmdData,
- uint32_t *pReplySize,
- void *pReplyData)
- {
- ALOGV("command");
- Parcel data, reply;
- data.writeInterfaceToken(IEffect::getInterfaceDescriptor());
- data.writeInt32(cmdCode);
- int size = cmdSize;
- if (pCmdData == NULL) {
- size = 0;
- }
- data.writeInt32(size);
- if (size) {
- data.write(pCmdData, size);
- }
- if (pReplySize == NULL) {
- size = 0;
- } else {
- size = *pReplySize;
- }
- data.writeInt32(size);
-
- status_t status = remote()->transact(COMMAND, data, &reply);
- if (status == NO_ERROR) {
- status = reply.readInt32();
- }
- if (status != NO_ERROR) {
- if (pReplySize != NULL)
- *pReplySize = 0;
- return status;
- }
-
- size = reply.readInt32();
- if (size != 0 && pReplyData != NULL && pReplySize != NULL) {
- reply.read(pReplyData, size);
- *pReplySize = size;
- }
- return status;
- }
-
- void disconnect()
- {
- ALOGV("disconnect");
- Parcel data, reply;
- data.writeInterfaceToken(IEffect::getInterfaceDescriptor());
- remote()->transact(DISCONNECT, data, &reply);
- return;
- }
-
- virtual sp<IMemory> getCblk() const
- {
- Parcel data, reply;
- sp<IMemory> cblk;
- data.writeInterfaceToken(IEffect::getInterfaceDescriptor());
- status_t status = remote()->transact(GET_CBLK, data, &reply);
- if (status == NO_ERROR) {
- cblk = interface_cast<IMemory>(reply.readStrongBinder());
- if (cblk != 0 && cblk->unsecurePointer() == NULL) {
- cblk.clear();
- }
- }
- return cblk;
- }
- };
-
-IMPLEMENT_META_INTERFACE(Effect, "android.media.IEffect");
-
-// ----------------------------------------------------------------------
-
-status_t BnEffect::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
- switch (code) {
- case ENABLE: {
- ALOGV("ENABLE");
- CHECK_INTERFACE(IEffect, data, reply);
- reply->writeInt32(enable());
- return NO_ERROR;
- } break;
-
- case DISABLE: {
- ALOGV("DISABLE");
- CHECK_INTERFACE(IEffect, data, reply);
- reply->writeInt32(disable());
- return NO_ERROR;
- } break;
-
- case COMMAND: {
- ALOGV("COMMAND");
- CHECK_INTERFACE(IEffect, data, reply);
- uint32_t cmdCode = data.readInt32();
- uint32_t cmdSize = data.readInt32();
- char *cmd = NULL;
- if (cmdSize) {
- if (cmdSize > EFFECT_PARAM_SIZE_MAX) {
- reply->writeInt32(NO_MEMORY);
- return NO_ERROR;
- }
- cmd = (char *)calloc(cmdSize, 1);
- if (cmd == NULL) {
- reply->writeInt32(NO_MEMORY);
- return NO_ERROR;
- }
- data.read(cmd, cmdSize);
- }
- uint32_t replySize = data.readInt32();
- uint32_t replySz = replySize;
- char *resp = NULL;
- if (replySize) {
- if (replySize > EFFECT_PARAM_SIZE_MAX) {
- free(cmd);
- reply->writeInt32(NO_MEMORY);
- return NO_ERROR;
- }
- resp = (char *)calloc(replySize, 1);
- if (resp == NULL) {
- free(cmd);
- reply->writeInt32(NO_MEMORY);
- return NO_ERROR;
- }
- }
- status_t status = command(cmdCode, cmdSize, cmd, &replySz, resp);
- reply->writeInt32(status);
- if (status == NO_ERROR) {
- if (replySz < replySize) {
- replySize = replySz;
- }
- reply->writeInt32(replySize);
- if (replySize) {
- reply->write(resp, replySize);
- }
- }
- if (cmd) {
- free(cmd);
- }
- if (resp) {
- free(resp);
- }
- return NO_ERROR;
- } break;
-
- case DISCONNECT: {
- ALOGV("DISCONNECT");
- CHECK_INTERFACE(IEffect, data, reply);
- disconnect();
- return NO_ERROR;
- } break;
-
- case GET_CBLK: {
- CHECK_INTERFACE(IEffect, data, reply);
- reply->writeStrongBinder(IInterface::asBinder(getCblk()));
- return NO_ERROR;
- } break;
-
- default:
- return BBinder::onTransact(code, data, reply, flags);
- }
-}
-
-// ----------------------------------------------------------------------------
-
-} // namespace android
diff --git a/media/libaudioclient/IEffectClient.cpp b/media/libaudioclient/IEffectClient.cpp
deleted file mode 100644
index 3f2c67d..0000000
--- a/media/libaudioclient/IEffectClient.cpp
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
-**
-** Copyright 2010, 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_NDEBUG 0
-#define LOG_TAG "IEffectClient"
-#include <utils/Log.h>
-#include <stdint.h>
-#include <sys/types.h>
-#include <media/IEffectClient.h>
-
-namespace android {
-
-enum {
- CONTROL_STATUS_CHANGED = IBinder::FIRST_CALL_TRANSACTION,
- ENABLE_STATUS_CHANGED,
- COMMAND_EXECUTED
-};
-
-class BpEffectClient: public BpInterface<IEffectClient>
-{
-public:
- explicit BpEffectClient(const sp<IBinder>& impl)
- : BpInterface<IEffectClient>(impl)
- {
- }
-
- void controlStatusChanged(bool controlGranted)
- {
- ALOGV("controlStatusChanged");
- Parcel data, reply;
- data.writeInterfaceToken(IEffectClient::getInterfaceDescriptor());
- data.writeInt32((uint32_t)controlGranted);
- remote()->transact(CONTROL_STATUS_CHANGED, data, &reply, IBinder::FLAG_ONEWAY);
- }
-
- void enableStatusChanged(bool enabled)
- {
- ALOGV("enableStatusChanged");
- Parcel data, reply;
- data.writeInterfaceToken(IEffectClient::getInterfaceDescriptor());
- data.writeInt32((uint32_t)enabled);
- remote()->transact(ENABLE_STATUS_CHANGED, data, &reply, IBinder::FLAG_ONEWAY);
- }
-
- void commandExecuted(uint32_t cmdCode,
- uint32_t cmdSize,
- void *pCmdData,
- uint32_t replySize,
- void *pReplyData)
- {
- ALOGV("commandExecuted");
- Parcel data, reply;
- data.writeInterfaceToken(IEffectClient::getInterfaceDescriptor());
- data.writeInt32(cmdCode);
- int size = cmdSize;
- if (pCmdData == NULL) {
- size = 0;
- }
- data.writeInt32(size);
- if (size) {
- data.write(pCmdData, size);
- }
- size = replySize;
- if (pReplyData == NULL) {
- size = 0;
- }
- data.writeInt32(size);
- if (size) {
- data.write(pReplyData, size);
- }
- remote()->transact(COMMAND_EXECUTED, data, &reply, IBinder::FLAG_ONEWAY);
- }
-
-};
-
-IMPLEMENT_META_INTERFACE(EffectClient, "android.media.IEffectClient");
-
-// ----------------------------------------------------------------------
-
-status_t BnEffectClient::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
- switch (code) {
- case CONTROL_STATUS_CHANGED: {
- ALOGV("CONTROL_STATUS_CHANGED");
- CHECK_INTERFACE(IEffectClient, data, reply);
- bool hasControl = (bool)data.readInt32();
- controlStatusChanged(hasControl);
- return NO_ERROR;
- } break;
- case ENABLE_STATUS_CHANGED: {
- ALOGV("ENABLE_STATUS_CHANGED");
- CHECK_INTERFACE(IEffectClient, data, reply);
- bool enabled = (bool)data.readInt32();
- enableStatusChanged(enabled);
- return NO_ERROR;
- } break;
- case COMMAND_EXECUTED: {
- ALOGV("COMMAND_EXECUTED");
- CHECK_INTERFACE(IEffectClient, data, reply);
- uint32_t cmdCode = data.readInt32();
- uint32_t cmdSize = data.readInt32();
- char *cmd = NULL;
- if (cmdSize) {
- cmd = (char *)malloc(cmdSize);
- data.read(cmd, cmdSize);
- }
- uint32_t replySize = data.readInt32();
- char *resp = NULL;
- if (replySize) {
- resp = (char *)malloc(replySize);
- data.read(resp, replySize);
- }
- commandExecuted(cmdCode, cmdSize, cmd, replySize, resp);
- if (cmd) {
- free(cmd);
- }
- if (resp) {
- free(resp);
- }
- return NO_ERROR;
- } break;
- default:
- return BBinder::onTransact(code, data, reply, flags);
- }
-}
-
-// ----------------------------------------------------------------------------
-
-} // namespace android
diff --git a/media/libaudioclient/aidl/android/media/IEffect.aidl b/media/libaudioclient/aidl/android/media/IEffect.aidl
new file mode 100644
index 0000000..9548e46
--- /dev/null
+++ b/media/libaudioclient/aidl/android/media/IEffect.aidl
@@ -0,0 +1,65 @@
+/*
+ * 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 android.media;
+
+import android.media.SharedFileRegion;
+
+/**
+ * The IEffect interface enables control of the effect module activity and parameters.
+ *
+ * @hide
+ */
+interface IEffect {
+ /**
+ * Activates the effect module by connecting it to the audio path.
+ * @return a status_t code.
+ */
+ int enable();
+
+ /**
+ * Deactivates the effect module by disconnecting it from the audio path.
+ * @return a status_t code.
+ */
+ int disable();
+
+ /**
+ * Sends control, reads or writes parameters. Same behavior as the command() method in the
+ * effect control interface.
+ * Refer to system/audio_effect.h for a description of the valid command codes and their
+ * associated parameter and return messages. The cmdData and response parameters are expected to
+ * contain the respective types in a standard C memory layout.
+ *
+ * TODO(ytai): replace opaque byte arrays with strongly typed parameters.
+ */
+ int command(int cmdCode, in byte[] cmdData, int maxResponseSize, out byte[] response);
+
+ /**
+ * Disconnects the IEffect interface from the effect module.
+ * This will also delete the effect module and release the effect engine in the library if this
+ * is the last client disconnected. To release control of the effect module, the application can
+ * disconnect or delete the IEffect interface.
+ */
+ void disconnect();
+
+ /**
+ * returns a pointer to a shared memory area used to pass multiple parameters to the effect
+ * module without multiplying the binder calls.
+ *
+ * TODO(ytai): Explain how this should be used exactly.
+ */
+ SharedFileRegion getCblk();
+}
diff --git a/media/libaudioclient/aidl/android/media/IEffectClient.aidl b/media/libaudioclient/aidl/android/media/IEffectClient.aidl
new file mode 100644
index 0000000..d1e331c
--- /dev/null
+++ b/media/libaudioclient/aidl/android/media/IEffectClient.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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 android.media;
+
+/**
+ * A callback interface for getting effect-related notifications.
+ *
+ * @hide
+ */
+interface IEffectClient {
+ /**
+ * Called whenever the status of granting control over the effect to the application
+ * has changed.
+ * @param controlGranted true iff the application has the control of the effect module.
+ */
+ oneway void controlStatusChanged(boolean controlGranted);
+
+ /**
+ * Called whenever the effect has been enabled or disabled. Received only if the client is not
+ * currently controlling the effect.
+ * @param enabled true if the effect module has been activated, false if deactivated.
+ */
+ oneway void enableStatusChanged(boolean enabled);
+
+ /**
+ * A command has been send to the effect engine. Received only if the client is not currently
+ * controlling the effect. See IEffect.command() for a description of buffer contents.
+ *
+ * TODO(ytai): replace opaque byte arrays with strongly typed parameters.
+ */
+ oneway void commandExecuted(int cmdCode, in byte[] cmdData, in byte[] replyData);
+}
diff --git a/media/libaudioclient/include/media/AudioEffect.h b/media/libaudioclient/include/media/AudioEffect.h
index 3d4bb4e..8371711 100644
--- a/media/libaudioclient/include/media/AudioEffect.h
+++ b/media/libaudioclient/include/media/AudioEffect.h
@@ -22,8 +22,6 @@
#include <media/IAudioFlinger.h>
#include <media/IAudioPolicyService.h>
-#include <media/IEffect.h>
-#include <media/IEffectClient.h>
#include <media/AudioSystem.h>
#include <system/audio_effect.h>
@@ -31,6 +29,9 @@
#include <utils/Errors.h>
#include <binder/IInterface.h>
+#include "android/media/IEffect.h"
+#include "android/media/BnEffectClient.h"
+
namespace android {
@@ -549,45 +550,43 @@
// IEffectClient
virtual void controlStatusChanged(bool controlGranted);
virtual void enableStatusChanged(bool enabled);
- virtual void commandExecuted(uint32_t cmdCode,
- uint32_t cmdSize,
- void *pCmdData,
- uint32_t replySize,
- void *pReplyData);
+ virtual void commandExecuted(int32_t cmdCode,
+ const std::vector<uint8_t>& cmdData,
+ const std::vector<uint8_t>& replyData);
private:
// Implements the IEffectClient interface
class EffectClient :
- public android::BnEffectClient, public android::IBinder::DeathRecipient
+ public media::BnEffectClient, public android::IBinder::DeathRecipient
{
public:
EffectClient(AudioEffect *effect) : mEffect(effect){}
// IEffectClient
- virtual void controlStatusChanged(bool controlGranted) {
+ binder::Status controlStatusChanged(bool controlGranted) override {
sp<AudioEffect> effect = mEffect.promote();
if (effect != 0) {
effect->controlStatusChanged(controlGranted);
}
+ return binder::Status::ok();
}
- virtual void enableStatusChanged(bool enabled) {
+ binder::Status enableStatusChanged(bool enabled) override {
sp<AudioEffect> effect = mEffect.promote();
if (effect != 0) {
effect->enableStatusChanged(enabled);
}
+ return binder::Status::ok();
}
- virtual void commandExecuted(uint32_t cmdCode,
- uint32_t cmdSize,
- void *pCmdData,
- uint32_t replySize,
- void *pReplyData) {
+ binder::Status commandExecuted(int32_t cmdCode,
+ const std::vector<uint8_t>& cmdData,
+ const std::vector<uint8_t>& replyData) override {
sp<AudioEffect> effect = mEffect.promote();
if (effect != 0) {
- effect->commandExecuted(
- cmdCode, cmdSize, pCmdData, replySize, pReplyData);
+ effect->commandExecuted(cmdCode, cmdData, replyData);
}
+ return binder::Status::ok();
}
// IBinder::DeathRecipient
@@ -604,7 +603,7 @@
void binderDied();
- sp<IEffect> mIEffect; // IEffect binder interface
+ sp<media::IEffect> mIEffect; // IEffect binder interface
sp<EffectClient> mIEffectClient; // IEffectClient implementation
sp<IMemory> mCblkMemory; // shared memory for deferred parameter setting
effect_param_cblk_t* mCblk = nullptr; // control block for deferred parameter setting
diff --git a/media/libaudioclient/include/media/IAudioFlinger.h b/media/libaudioclient/include/media/IAudioFlinger.h
index 612ce7a..b950d0f 100644
--- a/media/libaudioclient/include/media/IAudioFlinger.h
+++ b/media/libaudioclient/include/media/IAudioFlinger.h
@@ -33,14 +33,14 @@
#include <system/audio.h>
#include <system/audio_effect.h>
#include <system/audio_policy.h>
-#include <media/IEffect.h>
-#include <media/IEffectClient.h>
#include <utils/String8.h>
#include <media/MicrophoneInfo.h>
#include <vector>
#include "android/media/IAudioRecord.h"
#include "android/media/IAudioTrackCallback.h"
+#include "android/media/IEffect.h"
+#include "android/media/IEffectClient.h"
namespace android {
@@ -463,9 +463,9 @@
uint32_t preferredTypeFlag,
effect_descriptor_t *pDescriptor) const = 0;
- virtual sp<IEffect> createEffect(
+ virtual sp<media::IEffect> createEffect(
effect_descriptor_t *pDesc,
- const sp<IEffectClient>& client,
+ const sp<media::IEffectClient>& client,
int32_t priority,
// AudioFlinger doesn't take over handle reference from client
audio_io_handle_t output,
diff --git a/media/libaudioclient/include/media/IEffect.h b/media/libaudioclient/include/media/IEffect.h
deleted file mode 100644
index ff04869..0000000
--- a/media/libaudioclient/include/media/IEffect.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2010 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_IEFFECT_H
-#define ANDROID_IEFFECT_H
-
-#include <utils/RefBase.h>
-#include <binder/IInterface.h>
-#include <binder/Parcel.h>
-#include <binder/IMemory.h>
-
-namespace android {
-
-class IEffect: public IInterface
-{
-public:
- DECLARE_META_INTERFACE(Effect);
-
- virtual status_t enable() = 0;
-
- virtual status_t disable() = 0;
-
- virtual status_t command(uint32_t cmdCode,
- uint32_t cmdSize,
- void *pCmdData,
- uint32_t *pReplySize,
- void *pReplyData) = 0;
-
- virtual void disconnect() = 0;
-
- virtual sp<IMemory> getCblk() const = 0;
-};
-
-// ----------------------------------------------------------------------------
-
-class BnEffect: public BnInterface<IEffect>
-{
-public:
- virtual status_t onTransact( uint32_t code,
- const Parcel& data,
- Parcel* reply,
- uint32_t flags = 0);
-};
-
-}; // namespace android
-
-#endif // ANDROID_IEFFECT_H
diff --git a/media/libaudioclient/include/media/IEffectClient.h b/media/libaudioclient/include/media/IEffectClient.h
deleted file mode 100644
index 2f78c98..0000000
--- a/media/libaudioclient/include/media/IEffectClient.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2010 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_IEFFECTCLIENT_H
-#define ANDROID_IEFFECTCLIENT_H
-
-#include <utils/RefBase.h>
-#include <binder/IInterface.h>
-#include <binder/Parcel.h>
-#include <binder/IMemory.h>
-
-namespace android {
-
-class IEffectClient: public IInterface
-{
-public:
- DECLARE_META_INTERFACE(EffectClient);
-
- virtual void controlStatusChanged(bool controlGranted) = 0;
- virtual void enableStatusChanged(bool enabled) = 0;
- virtual void commandExecuted(uint32_t cmdCode,
- uint32_t cmdSize,
- void *pCmdData,
- uint32_t replySize,
- void *pReplyData) = 0;
-};
-
-// ----------------------------------------------------------------------------
-
-class BnEffectClient: public BnInterface<IEffectClient>
-{
-public:
- virtual status_t onTransact( uint32_t code,
- const Parcel& data,
- Parcel* reply,
- uint32_t flags = 0);
-};
-
-}; // namespace android
-
-#endif // ANDROID_IEFFECTCLIENT_H