Refactor AudioEffect callback to interface
Refactor AudioEffect callback from static function pointer
with pointer args to callback interface.
- Removes need for event enum, user cookie, and opaque arg
ptr.
- Replace effect_callback_t with IAudioEffectCallback listener
interface for separate notifications for each event type.
- Duplicate set/constructor methods to provide for incremental
refactor.
- LegacyCallbackWrapper to wrap legacy_callback_t consuming methods
- Retain wp<IAudioTrackCallback> to refcount and avoid ownership
cycles.
Related-to: Id75c8866bdfa528d37cf1f93e41e917568c4a147
Bug: 199156212
Test: Compiles. To be verified.
Change-Id: I6e49abd463196c1e89f3ca0578e9cd84c5a7f89e
diff --git a/media/libaudioclient/AudioEffect.cpp b/media/libaudioclient/AudioEffect.cpp
index 62f863d..16ae246 100644
--- a/media/libaudioclient/AudioEffect.cpp
+++ b/media/libaudioclient/AudioEffect.cpp
@@ -61,8 +61,7 @@
status_t AudioEffect::set(const effect_uuid_t *type,
const effect_uuid_t *uuid,
int32_t priority,
- effect_callback_t cbf,
- void* user,
+ const wp<IAudioEffectCallback>& callback,
audio_session_t sessionId,
audio_io_handle_t io,
const AudioDeviceTypeAddr& device,
@@ -73,7 +72,7 @@
sp<IMemory> cblk;
int enabled;
- ALOGV("set %p mUserData: %p uuid: %p timeLow %08x", this, user, type, type ? type->timeLow : 0);
+ ALOGV("set %p uuid: %p timeLow %08x", this, type, type ? type->timeLow : 0);
if (mIEffect != 0) {
ALOGW("Effect already in use");
@@ -96,9 +95,8 @@
}
mProbe = probe;
mPriority = priority;
- mCbf = cbf;
- mUserData = user;
mSessionId = sessionId;
+ mCallback = callback;
memset(&mDescriptor, 0, sizeof(effect_descriptor_t));
mDescriptor.type = *(type != NULL ? type : EFFECT_UUID_NULL);
@@ -184,11 +182,60 @@
return mStatus;
}
+namespace {
+class LegacyCallbackWrapper : public AudioEffect::IAudioEffectCallback {
+ public:
+ LegacyCallbackWrapper(AudioEffect::legacy_callback_t callback, void* user):
+ mCallback(callback), mUser(user) {}
+ private:
+ void onControlStatusChanged(bool isGranted) override {
+ mCallback(AudioEffect::EVENT_CONTROL_STATUS_CHANGED, mUser, &isGranted);
+ }
+
+ void onEnableStatusChanged(bool isEnabled) override {
+ mCallback(AudioEffect::EVENT_ENABLE_STATUS_CHANGED, mUser, &isEnabled);
+ }
+
+ void onParameterChanged(std::vector<uint8_t> param) override {
+ mCallback(AudioEffect::EVENT_PARAMETER_CHANGED, mUser, param.data());
+ }
+
+ void onError(status_t errorCode) override {
+ mCallback(AudioEffect::EVENT_ERROR, mUser, &errorCode);
+ }
+
+ void onFramesProcessed(int32_t framesProcessed) override {
+ mCallback(AudioEffect::EVENT_FRAMES_PROCESSED, mUser, &framesProcessed);
+ }
+
+ const AudioEffect::legacy_callback_t mCallback;
+ void* const mUser;
+};
+} // namespace
+
+status_t AudioEffect::set(const effect_uuid_t *type,
+ const effect_uuid_t *uuid,
+ int32_t priority,
+ legacy_callback_t cbf,
+ void* user,
+ audio_session_t sessionId,
+ audio_io_handle_t io,
+ const AudioDeviceTypeAddr& device,
+ bool probe,
+ bool notifyFramesProcessed)
+{
+ if (cbf != nullptr) {
+ mLegacyWrapper = sp<LegacyCallbackWrapper>::make(cbf, user);
+ } else if (user != nullptr) {
+ LOG_ALWAYS_FATAL("%s: User provided without callback", __func__);
+ }
+ return set(type, uuid, priority, mLegacyWrapper, sessionId, io, device, probe,
+ notifyFramesProcessed);
+}
status_t AudioEffect::set(const char *typeStr,
const char *uuidStr,
int32_t priority,
- effect_callback_t cbf,
- void* user,
+ const wp<IAudioEffectCallback>& callback,
audio_session_t sessionId,
audio_io_handle_t io,
const AudioDeviceTypeAddr& device,
@@ -210,11 +257,29 @@
pUuid = &uuid;
}
- return set(pType, pUuid, priority, cbf, user, sessionId, io,
+ return set(pType, pUuid, priority, callback, sessionId, io,
device, probe, notifyFramesProcessed);
}
-
+status_t AudioEffect::set(const char *typeStr,
+ const char *uuidStr,
+ int32_t priority,
+ legacy_callback_t cbf,
+ void* user,
+ audio_session_t sessionId,
+ audio_io_handle_t io,
+ const AudioDeviceTypeAddr& device,
+ bool probe,
+ bool notifyFramesProcessed)
+{
+ if (cbf != nullptr) {
+ mLegacyWrapper = sp<LegacyCallbackWrapper>::make(cbf, user);
+ } else if (user != nullptr) {
+ LOG_ALWAYS_FATAL("%s: User provided without callback", __func__);
+ }
+ return set(typeStr, uuidStr, priority, mLegacyWrapper, sessionId, io, device, probe,
+ notifyFramesProcessed);
+}
AudioEffect::~AudioEffect()
{
ALOGV("Destructor %p", this);
@@ -468,9 +533,9 @@
{
ALOGW("IEffect died");
mStatus = DEAD_OBJECT;
- if (mCbf != NULL) {
- status_t status = DEAD_OBJECT;
- mCbf(EVENT_ERROR, mUserData, &status);
+ auto cb = mCallback.promote();
+ if (cb != nullptr) {
+ cb->onError(mStatus);
}
mIEffect.clear();
}
@@ -479,8 +544,8 @@
void AudioEffect::controlStatusChanged(bool controlGranted)
{
- ALOGV("controlStatusChanged %p control %d callback %p mUserData %p", this, controlGranted, mCbf,
- mUserData);
+ auto cb = mCallback.promote();
+ ALOGV("controlStatusChanged %p control %d callback %p", this, controlGranted, cb.get());
if (controlGranted) {
if (mStatus == ALREADY_EXISTS) {
mStatus = NO_ERROR;
@@ -490,18 +555,19 @@
mStatus = ALREADY_EXISTS;
}
}
- if (mCbf != NULL) {
- mCbf(EVENT_CONTROL_STATUS_CHANGED, mUserData, &controlGranted);
+ if (cb != nullptr) {
+ cb->onControlStatusChanged(controlGranted);
}
}
void AudioEffect::enableStatusChanged(bool enabled)
{
- ALOGV("enableStatusChanged %p enabled %d mCbf %p", this, enabled, mCbf);
+ auto cb = mCallback.promote();
+ ALOGV("enableStatusChanged %p enabled %d mCallback %p", this, enabled, cb.get());
if (mStatus == ALREADY_EXISTS) {
mEnabled = enabled;
- if (mCbf != NULL) {
- mCbf(EVENT_ENABLE_STATUS_CHANGED, mUserData, &enabled);
+ if (cb != nullptr) {
+ cb->onEnableStatusChanged(enabled);
}
}
}
@@ -513,19 +579,20 @@
if (cmdData.empty() || replyData.empty()) {
return;
}
-
- if (mCbf != NULL && cmdCode == EFFECT_CMD_SET_PARAM) {
+ auto cb = mCallback.promote();
+ if (cb != nullptr && cmdCode == EFFECT_CMD_SET_PARAM) {
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);
+ cb->onParameterChanged(std::move(cmdDataCopy));
}
}
void AudioEffect::framesProcessed(int32_t frames)
{
- if (mCbf != NULL) {
- mCbf(EVENT_FRAMES_PROCESSED, mUserData, &frames);
+ auto cb = mCallback.promote();
+ if (cb != nullptr) {
+ cb->onFramesProcessed(frames);
}
}