Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a1405bb6 authored by Atneya Nair's avatar Atneya Nair Committed by Android (Google) Code Review
Browse files

Merge "Refactor AudioEffect callback to interface"

parents 701b0a16 47156076
Loading
Loading
Loading
Loading
+91 −24
Original line number Diff line number Diff line
@@ -61,8 +61,7 @@ AudioEffect::AudioEffect(const android::content::AttributionSourceState& attribu
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 @@ status_t AudioEffect::set(const effect_uuid_t *type,
    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 @@ status_t AudioEffect::set(const effect_uuid_t *type,
    }
    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);
@@ -187,11 +185,60 @@ status_t AudioEffect::set(const effect_uuid_t *type,
    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,
@@ -213,11 +260,29 @@ status_t AudioEffect::set(const char *typeStr,
        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);
@@ -471,9 +536,9 @@ void AudioEffect::binderDied()
{
    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();
}
@@ -482,8 +547,8 @@ void AudioEffect::binderDied()

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;
@@ -493,18 +558,19 @@ void AudioEffect::controlStatusChanged(bool controlGranted)
            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);
        }
    }
}
@@ -516,19 +582,20 @@ void AudioEffect::commandExecuted(int32_t cmdCode,
    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);
    }
}

+84 −21
Original line number Diff line number Diff line
@@ -277,7 +277,7 @@ public:
    static status_t removeStreamDefaultEffect(audio_unique_id_t id);

    /*
     * Events used by callback function (effect_callback_t).
     * Events used by callback function (legacy_callback_t).
     */
    enum event_type {
        EVENT_CONTROL_STATUS_CHANGED = 0,
@@ -287,6 +287,47 @@ public:
        EVENT_FRAMES_PROCESSED = 4,
    };

    class IAudioEffectCallback : public virtual RefBase {
        friend AudioEffect;
     protected:
        /* The event is received when an application loses or
         * gains the control of the effect engine. Loss of control happens
         * if another application requests the use of the engine by creating an AudioEffect for
         * the same effect type but with a higher priority. Control is returned when the
         * application having the control deletes its AudioEffect object.
         * @param isGranted: True if control has been granted. False if stolen.
         */
        virtual void onControlStatusChanged([[maybe_unused]] bool isGranted) {}

        /* The event is received by all applications not having the
         * control of the effect engine when the effect is enabled or disabled.
         * @param isEnabled: True if enabled. False if disabled.
         */
        virtual void onEnableStatusChanged([[maybe_unused]] bool isEnabled) {}

        /* The event is received by all applications not having the
         * control of the effect engine when an effect parameter is changed.
         * @param param: A vector containing the raw bytes of a effect_param_type containing
         *   raw data representing a param type, value pair.
         */
        // TODO pass an AIDL parcel instead of effect_param_type
        virtual void onParameterChanged([[maybe_unused]] std::vector<uint8_t> param) {}

        /* The event is received when the binder connection to the mediaserver
         * is no longer valid. Typically the server has been killed.
         * @param errorCode: A code representing the type of error.
         */
        virtual void onError([[maybe_unused]] status_t errorCode) {}


        /* The event is received when the audio server has processed a block of
         * data.
         * @param framesProcessed: The number of frames the audio server has
         *   processed.
         */
        virtual void onFramesProcessed([[maybe_unused]] int32_t framesProcessed) {}
    };

    /* Callback function notifying client application of a change in effect engine state or
     * configuration.
     * An effect engine can be shared by several applications but only one has the control
@@ -315,7 +356,7 @@ public:
     *  - EVENT_ERROR:  status_t indicating the error (DEAD_OBJECT when media server dies).
     */

    typedef void (*effect_callback_t)(int32_t event, void* user, void *info);
    typedef void (*legacy_callback_t)(int32_t event, void* user, void *info);


    /* Constructor.
@@ -360,7 +401,7 @@ public:
     * priority:    requested priority for effect control: the priority level corresponds to the
     *      value of priority parameter: negative values indicate lower priorities, positive values
     *      higher priorities, 0 being the normal priority.
     * cbf:         optional callback function (see effect_callback_t)
     * cbf:         optional callback function (see legacy_callback_t)
     * user:        pointer to context for use by the callback receiver.
     * sessionId:   audio session this effect is associated to.
     *      If equal to AUDIO_SESSION_OUTPUT_MIX, the effect will be global to
@@ -383,10 +424,20 @@ public:
     *  - NO_INIT: audio flinger or audio hardware not initialized
     */
            status_t    set(const effect_uuid_t *type,
                            const effect_uuid_t *uuid = NULL,
                            const effect_uuid_t *uuid = nullptr,
                            int32_t priority = 0,
                            effect_callback_t cbf = NULL,
                            void* user = NULL,
                            const wp<IAudioEffectCallback>& callback = nullptr,
                            audio_session_t sessionId = AUDIO_SESSION_OUTPUT_MIX,
                            audio_io_handle_t io = AUDIO_IO_HANDLE_NONE,
                            const AudioDeviceTypeAddr& device = {},
                            bool probe = false,
                            bool notifyFramesProcessed = false);

            status_t    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_SESSION_OUTPUT_MIX,
                            audio_io_handle_t io = AUDIO_IO_HANDLE_NONE,
                            const AudioDeviceTypeAddr& device = {},
@@ -396,10 +447,21 @@ public:
     * Same as above but with type and uuid specified by character strings.
     */
            status_t    set(const char *typeStr,
                            const char *uuidStr = NULL,
                            const char *uuidStr = nullptr,
                            int32_t priority = 0,
                            effect_callback_t cbf = NULL,
                            void* user = NULL,
                            const wp<IAudioEffectCallback>& callback = nullptr,
                            audio_session_t sessionId = AUDIO_SESSION_OUTPUT_MIX,
                            audio_io_handle_t io = AUDIO_IO_HANDLE_NONE,
                            const AudioDeviceTypeAddr& device = {},
                            bool probe = false,
                            bool notifyFramesProcessed = false);


            status_t    set(const char *typeStr,
                            const char *uuidStr,
                            int32_t priority,
                            legacy_callback_t cbf,
                            void* user,
                            audio_session_t sessionId = AUDIO_SESSION_OUTPUT_MIX,
                            audio_io_handle_t io = AUDIO_IO_HANDLE_NONE,
                            const AudioDeviceTypeAddr& device = {},
@@ -540,10 +602,11 @@ protected:
     int32_t                  mPriority = 0;      // priority for effect control
     status_t                 mStatus = NO_INIT;  // effect status
     bool                     mProbe = false;     // effect created in probe mode: all commands
                                                 // are no ops because mIEffect is NULL
     effect_callback_t       mCbf = nullptr;     // callback function for status, control and
                                                 // are no ops because mIEffect is nullptr

     wp<IAudioEffectCallback> mCallback = nullptr; // callback interface for status, control and
                                                   // parameter changes notifications
     void*                   mUserData = nullptr;// client context for callback function
     sp<IAudioEffectCallback> mLegacyWrapper = nullptr;
     effect_descriptor_t      mDescriptor = {};   // effect descriptor
     int32_t                  mId = -1;           // system wide unique effect engine instance ID
     Mutex                    mLock;              // Mutex for mEnabled access