/*
 * Copyright (C) 2015 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 "volume_listener"
//#define LOG_NDEBUG 0
#include <stdlib.h>
#include <dlfcn.h>

#include <cutils/list.h>
#include <cutils/log.h>
#include <hardware/audio_effect.h>
#include <cutils/properties.h>
#include <platform_api.h>

#define PRIMARY_HAL_PATH XSTR(LIB_AUDIO_HAL)
#define XSTR(x) STR(x)
#define STR(x) #x

#define VOL_FLAG ( EFFECT_FLAG_TYPE_INSERT | \
                   EFFECT_FLAG_VOLUME_IND | \
                   EFFECT_FLAG_DEVICE_IND | \
                   EFFECT_FLAG_OFFLOAD_SUPPORTED | \
                   EFFECT_FLAG_NO_PROCESS)

#define PRINT_STREAM_TYPE(i) ALOGV("descriptor found and is of stream type %s ",\
                                                            i == MUSIC?"MUSIC": \
                                                            i == RING?"RING": \
                                                            i == ALARM?"ALARM": \
                                                            i == VOICE_CALL?"Voice_call": \
                                                            i == NOTIFICATION?"Notification":\
                                                            "--INVALID--"); \

#define MAX_GAIN_LEVELS 5

#define AHAL_GAIN_DEPENDENT_INTERFACE_FUNCTION "audio_hw_send_gain_dep_calibration"
#define AHAL_GAIN_GET_MAPPING_TABLE "audio_hw_get_gain_level_mapping"
#define DEFAULT_CAL_STEP 0

enum {
    VOL_LISTENER_STATE_UNINITIALIZED,
    VOL_LISTENER_STATE_INITIALIZED,
    VOL_LISTENER_STATE_ACTIVE,
};

typedef struct vol_listener_context_s vol_listener_context_t;
static const struct effect_interface_s effect_interface;

/* flag to avoid multiple initialization */
static bool initialized = false;

/* current gain dep cal level that was pushed succesfully */
static int current_gain_dep_cal_level = -1;

enum STREAM_TYPE {
    MUSIC,
    RING,
    ALARM,
    VOICE_CALL,
    NOTIFICATION,
    MAX_STREAM_TYPES,
};

struct vol_listener_context_s {
    const struct effect_interface_s *itfe;
    struct listnode effect_list_node;
    effect_config_t config;
    const effect_descriptor_t *desc;
    uint32_t stream_type;
    uint32_t session_id;
    uint32_t state;
    uint32_t dev_id;
    float left_vol;
    float right_vol;
};

/* volume listener, music UUID: 08b8b058-0590-11e5-ac71-0025b32654a0 */
const effect_descriptor_t vol_listener_music_descriptor = {
    { 0x08b8b058, 0x0590, 0x11e5, 0xac71, { 0x00, 0x25, 0xb3, 0x26, 0x54, 0xa0 } },  // type
    { 0x08b8b058, 0x0590, 0x11e5, 0xac71, { 0x00, 0x25, 0xb3, 0x26, 0x54, 0xa0 } },  // uuid
    EFFECT_CONTROL_API_VERSION,
    VOL_FLAG,
    0, /* TODO */
    1,
    "Volume listener for Music",
    "Qualcomm Technologies Inc.",
};

/* volume listener, ring UUID: 0956df94-0590-11e5-bdbe-0025b32654a0 */
const effect_descriptor_t vol_listener_ring_descriptor = {
    { 0x0956df94, 0x0590, 0x11e5, 0xbdbe, { 0x00, 0x25, 0xb3, 0x26, 0x54, 0xa0 } }, // type
    { 0x0956df94, 0x0590, 0x11e5, 0xbdbe, { 0x00, 0x25, 0xb3, 0x26, 0x54, 0xa0 } }, // uuid
    EFFECT_CONTROL_API_VERSION,
    VOL_FLAG,
    0, /* TODO */
    1,
    "Volume listener for ring",
    "Qualcomm Technologies Inc",
};

/* volume listener, alarm UUID: 09f303e2-0590-11e5-8fdb-0025b32654a0 */
const effect_descriptor_t vol_listener_alarm_descriptor = {
    { 0x09f303e2, 0x0590, 0x11e5, 0x8fdb, { 0x00, 0x25, 0xb3, 0x26, 0x54, 0xa0 } }, // type
    { 0x09f303e2, 0x0590, 0x11e5, 0x8fdb, { 0x00, 0x25, 0xb3, 0x26, 0x54, 0xa0 } }, // uuid
    EFFECT_CONTROL_API_VERSION,
    VOL_FLAG,
    0, /* TODO */
    1,
    "Volume listener for alarm",
    "Qualcomm Technologies Inc",
};

/* volume listener, voice call UUID: 0ace5c08-0590-11e5-ae9e-0025b32654a0 */
const effect_descriptor_t vol_listener_voice_call_descriptor = {
    { 0x0ace5c08, 0x0590, 0x11e5, 0xae9e, { 0x00, 0x25, 0xb3, 0x26, 0x54, 0xa0 } }, // type
    { 0x0ace5c08, 0x0590, 0x11e5, 0xae9e, { 0x00, 0x25, 0xb3, 0x26, 0x54, 0xa0 } }, // uuid
    EFFECT_CONTROL_API_VERSION,
    VOL_FLAG,
    0, /* TODO */
    1,
    "Volume listener for voice call",
    "Qualcomm Technologies Inc",
};

/* volume listener, notification UUID: 0b776dde-0590-11e5-81ba-0025b32654a0 */
const effect_descriptor_t vol_listener_notification_descriptor = {
    { 0x0b776dde, 0x0590, 0x11e5, 0x81ba, { 0x00, 0x25, 0xb3, 0x26, 0x54, 0xa0 } }, // type
    { 0x0b776dde, 0x0590, 0x11e5, 0x81ba, { 0x00, 0x25, 0xb3, 0x26, 0x54, 0xa0 } }, // uuid
    EFFECT_CONTROL_API_VERSION,
    VOL_FLAG,
    0, /* TODO */
    1,
    "Volume listener for notification",
    "Qualcomm Technologies Inc",
};

static int total_volume_cal_step = MAX_GAIN_LEVELS;

// using gain level for non-drc volume curve
struct amp_db_and_gain_table  volume_curve_gain_mapping_table[MAX_VOLUME_CAL_STEPS] =
{
    /* Level 0 in the calibration database contains default calibration */
    { 0.001774, -55, 5 },
    { 0.501187,  -6, 4 },
    { 0.630957,  -4, 3 },
    { 0.794328,  -2, 2 },
    { 1.0,        0, 1 },
    { 0, 0, -1 },
    { 0, 0, -1 },
    { 0, 0, -1 },
    { 0, 0, -1 },
    { 0, 0, -1 },
    { 0, 0, -1 },
    { 0, 0, -1 },
    { 0, 0, -1 },
    { 0, 0, -1 },
    { 0, 0, -1 }
};

static const effect_descriptor_t *descriptors[] = {
    &vol_listener_music_descriptor,
    &vol_listener_ring_descriptor,
    &vol_listener_alarm_descriptor,
    &vol_listener_voice_call_descriptor,
    &vol_listener_notification_descriptor,
    NULL,
};

pthread_once_t once = PTHREAD_ONCE_INIT;
/* flag to indicate if init was success */
static int init_status;

/* current volume level for which gain dep cal level was selected */
static float current_vol = 0.0;

/* HAL interface to send calibration */
static bool (*send_gain_dep_cal)(int);

static int (*get_custom_gain_table)(struct amp_db_and_gain_table *, int);

/* if dumping allowed */
static bool dumping_enabled = false;

/* list of created effects. */
struct listnode vol_effect_list;

/* lock must be held when modifying or accessing created_effects_list */
pthread_mutex_t vol_listner_init_lock;

/*
 *  Local functions
 */
static void dump_list_l()
{
    struct listnode *node;
    vol_listener_context_t *context;

    ALOGW("DUMP_START :: ===========");

    list_for_each(node, &vol_effect_list) {
        context = node_to_item(node, struct vol_listener_context_s, effect_list_node);
        // dump stream_type / Device / session_id / left / righ volume
        ALOGW("%s: streamType [%s] Device [%d] state [%d] sessionID [%d] volume (L/R) [%f / %f] ",
                __func__,
                context->stream_type == MUSIC ? "MUSIC" :
                context->stream_type == RING ? "RING" :
                context->stream_type == ALARM ? "ALARM" :
                context->stream_type == VOICE_CALL ? "VOICE_CALL" :
                context->stream_type == NOTIFICATION ? "NOTIFICATION" : "--INVALID--",
                context->dev_id, context->state, context->session_id, context->left_vol,context->right_vol);
    }

    ALOGW("DUMP_END :: ===========");
}

static void check_and_set_gain_dep_cal()
{
    // iterate through list and make decision to set new gain dep cal level for speaker device
    // 1. find all usecase active on speaker
    // 2. find average of left and right for each usecase
    // 3. find the highest of all the active usecase
    // 4. if new value is different than the current value then load new calibration

    struct listnode *node = NULL;
    float new_vol = -1.0;
    int max_level = 0;
    vol_listener_context_t *context = NULL;
    if (dumping_enabled) {
        dump_list_l();
    }

    ALOGV("%s ==> Start ...", __func__);

    // select the highest volume on speaker device
    list_for_each(node, &vol_effect_list) {
        context = node_to_item(node, struct vol_listener_context_s, effect_list_node);
        if ((context->state == VOL_LISTENER_STATE_ACTIVE) &&
            (context->dev_id & AUDIO_DEVICE_OUT_SPEAKER) &&
            (new_vol < (context->left_vol + context->right_vol) / 2)) {
            new_vol = (context->left_vol + context->right_vol) / 2;
        }
    }

    if (new_vol != current_vol) {
        ALOGV("%s:: Change in decision :: current volume is %f new volume is %f",
              __func__, current_vol, new_vol);

        if (send_gain_dep_cal != NULL) {
            // send Gain dep cal level
            int gain_dep_cal_level = -1;

            if (new_vol >= 1 && total_volume_cal_step > 0) { // max amplitude, use highest DRC level
                gain_dep_cal_level = volume_curve_gain_mapping_table[total_volume_cal_step - 1].level;
            } else if (new_vol == -1) {
                gain_dep_cal_level = DEFAULT_CAL_STEP;
            } else if (new_vol == 0) {
                gain_dep_cal_level = volume_curve_gain_mapping_table[0].level;
            } else {
                for (max_level = 0; max_level + 1 < total_volume_cal_step; max_level++) {
                    if (new_vol < volume_curve_gain_mapping_table[max_level + 1].amp &&
                        new_vol >= volume_curve_gain_mapping_table[max_level].amp) {
                        gain_dep_cal_level = volume_curve_gain_mapping_table[max_level].level;
                        ALOGV("%s: volume(%f), gain dep cal selcetd %d ",
                              __func__, current_vol, gain_dep_cal_level);
                        break;
                    }
                }
            }

            // check here if previous gain dep cal level was not same
            if (gain_dep_cal_level != -1) {
                if (gain_dep_cal_level != current_gain_dep_cal_level) {
                    // decision made .. send new level now
                    if (!send_gain_dep_cal(gain_dep_cal_level)) {
                        ALOGE("%s: Failed to set gain dep cal level", __func__);
                    } else {
                        // Success in setting the gain dep cal level, store new level and Volume
                        if (dumping_enabled) {
                            ALOGW("%s: (old/new) Volume (%f/%f) (old/new) level (%d/%d)",
                                  __func__, current_vol, new_vol, current_gain_dep_cal_level,
                                  gain_dep_cal_level);
                        } else {
                            ALOGV("%s: Change in Cal::(old/new) Volume (%f/%f) (old/new) level (%d/%d)",
                                  __func__, current_vol, new_vol, current_gain_dep_cal_level,
                                  gain_dep_cal_level);
                        }
                        current_gain_dep_cal_level = gain_dep_cal_level;
                        current_vol = new_vol;
                    }
                } else {
                    if (dumping_enabled) {
                        ALOGW("%s: volume changed but gain dep cal level is still the same",
                              __func__);
                    } else {
                        ALOGV("%s: volume changed but gain dep cal level is still the same",
                              __func__);
                    }
                }
            } else {
                ALOGW("%s: Failed to find gain dep cal level for volume %f", __func__, new_vol);
            }
        } else {
            ALOGE("%s: not able to send calibration, NULL function pointer",
                  __func__);
        }
    } else {
        ALOGV("%s:: volume not changed, stick to same config ..... ", __func__);
    }

    ALOGV("check_and_set_gain_dep_cal ==> End ");
}

/*
 * Effect Control Interface Implementation
 */

static inline int16_t clamp16(int32_t sample)
{
    if ((sample>>15) ^ (sample>>31))
        sample = 0x7FFF ^ (sample>>31);
    return sample;
}

static int vol_effect_command(effect_handle_t self,
                              uint32_t cmd_code, uint32_t cmd_size,
                              void *p_cmd_data, uint32_t *reply_size,
                              void *p_reply_data)
{
    vol_listener_context_t *context = (vol_listener_context_t *)self;
    int status = 0;

    ALOGV("%s Called ", __func__);
    pthread_mutex_lock(&vol_listner_init_lock);

    if (context == NULL || context->state == VOL_LISTENER_STATE_UNINITIALIZED) {
        ALOGE("%s: %s is NULL", __func__, (context == NULL) ?
              "context" : "context->state");
        status = -EINVAL;
        goto exit;
    }

    switch (cmd_code) {
    case EFFECT_CMD_INIT:
        ALOGV("%s :: cmd called EFFECT_CMD_INIT", __func__);
        if (p_reply_data == NULL || *reply_size != sizeof(int)) {
            ALOGE("%s: EFFECT_CMD_INIT: %s, sending -EINVAL", __func__,
                  (p_reply_data == NULL) ? "p_reply_data is NULL" :
                  "*reply_size != sizeof(int)");
            return -EINVAL;
        }
        *(int *)p_reply_data = 0;
        break;

    case EFFECT_CMD_SET_CONFIG:
        ALOGV("%s :: cmd called EFFECT_CMD_SET_CONFIG", __func__);
        if (p_cmd_data == NULL || cmd_size != sizeof(effect_config_t)
                || p_reply_data == NULL || reply_size == NULL || *reply_size != sizeof(int)) {
            return -EINVAL;
        }
        context->config = *(effect_config_t *)p_cmd_data;
        *(int *)p_reply_data = 0;
        break;

    case EFFECT_CMD_GET_CONFIG:
        ALOGV("%s :: cmd called EFFECT_CMD_GET_CONFIG", __func__);
        break;

    case EFFECT_CMD_RESET:
        ALOGV("%s :: cmd called EFFECT_CMD_RESET", __func__);
        break;

    case EFFECT_CMD_SET_AUDIO_MODE:
        ALOGV("%s :: cmd called EFFECT_CMD_SET_AUDIO_MODE", __func__);
        break;

    case EFFECT_CMD_OFFLOAD:
        ALOGV("%s :: cmd called EFFECT_CMD_OFFLOAD", __func__);
        if (p_reply_data == NULL || *reply_size != sizeof(int)) {
            ALOGE("%s: EFFECT_CMD_OFFLOAD: %s, sending -EINVAL", __func__,
                  (p_reply_data == NULL) ? "p_reply_data is NULL" :
                  "*reply_size != sizeof(int)");
            return -EINVAL;
        }
        *(int *)p_reply_data = 0;
        break;

    case EFFECT_CMD_ENABLE:
        ALOGV("%s :: cmd called EFFECT_CMD_ENABLE", __func__);
        if (p_reply_data == NULL || *reply_size != sizeof(int)) {
            ALOGE("%s: EFFECT_CMD_ENABLE: %s, sending -EINVAL", __func__,
                   (p_reply_data == NULL) ? "p_reply_data is NULL" :
                   "*reply_size != sizeof(int)");
            status = -EINVAL;
            goto exit;
        }

        if (context->state != VOL_LISTENER_STATE_INITIALIZED) {
            ALOGE("%s: EFFECT_CMD_ENABLE : state not INITIALIZED", __func__);
            status = -ENOSYS;
            goto exit;
        }

        context->state = VOL_LISTENER_STATE_ACTIVE;
        *(int *)p_reply_data = 0;

        // After changing the state and if device is speaker
        // recalculate gain dep cal level
        if (context->dev_id == AUDIO_DEVICE_OUT_SPEAKER) {
                check_and_set_gain_dep_cal();
        }

        break;

    case EFFECT_CMD_DISABLE:
        ALOGV("%s :: cmd called EFFECT_CMD_DISABLE", __func__);
        if (p_reply_data == NULL || *reply_size != sizeof(int)) {
            ALOGE("%s: EFFECT_CMD_DISABLE: %s, sending -EINVAL", __func__,
                  (p_reply_data == NULL) ? "p_reply_data is NULL" :
                  "*reply_size != sizeof(int)");
            status = -EINVAL;
            goto exit;
        }

        if (context->state != VOL_LISTENER_STATE_ACTIVE) {
            ALOGE("%s: EFFECT_CMD_ENABLE : state not ACTIVE", __func__);
            status = -ENOSYS;
            goto exit;
        }

        context->state = VOL_LISTENER_STATE_INITIALIZED;
        *(int *)p_reply_data = 0;

        // After changing the state and if device is speaker
        // recalculate gain dep cal level
        if (context->dev_id == AUDIO_DEVICE_OUT_SPEAKER) {
            check_and_set_gain_dep_cal();
        }

        break;

    case EFFECT_CMD_GET_PARAM:
        ALOGV("%s :: cmd called EFFECT_CMD_GET_PARAM", __func__);
        break;

    case EFFECT_CMD_SET_PARAM:
        ALOGV("%s :: cmd called EFFECT_CMD_SET_PARAM", __func__);
        break;

    case EFFECT_CMD_SET_DEVICE:
    {
        uint32_t new_device;
        bool recompute_gain_dep_cal_Level = false;
        ALOGV("cmd called EFFECT_CMD_SET_DEVICE ");

        if (p_cmd_data == NULL) {
            ALOGE("%s: EFFECT_CMD_SET_DEVICE: cmd data NULL", __func__);
            status = -EINVAL;
            goto exit;
        }

        new_device = *(uint32_t *)p_cmd_data;
        ALOGV("%s :: EFFECT_CMD_SET_DEVICE: (current/new) device (0x%x / 0x%x)",
               __func__, context->dev_id, new_device);

        // check if old or new device is speaker
        if ((context->dev_id ==  AUDIO_DEVICE_OUT_SPEAKER) ||
            (new_device == AUDIO_DEVICE_OUT_SPEAKER)) {
            recompute_gain_dep_cal_Level = true;
        }

        context->dev_id = new_device;

        if (recompute_gain_dep_cal_Level) {
            check_and_set_gain_dep_cal();
        }
    }
    break;

    case EFFECT_CMD_SET_VOLUME:
    {
        float left_vol = 0, right_vol = 0;
        bool recompute_gain_dep_cal_Level = false;

        ALOGV("cmd called EFFECT_CMD_SET_VOLUME");
        if (p_cmd_data == NULL || cmd_size != 2 * sizeof(uint32_t)) {
            ALOGE("%s: EFFECT_CMD_SET_VOLUME: %s", __func__, (p_cmd_data == NULL) ?
                  "p_cmd_data is NULL" : "cmd_size issue");
            status = -EINVAL;
            goto exit;
        }

        if (context->dev_id == AUDIO_DEVICE_OUT_SPEAKER) {
            recompute_gain_dep_cal_Level = true;
        }

        left_vol = (float)(*(uint32_t *)p_cmd_data) / (1 << 24);
        right_vol = (float)(*((uint32_t *)p_cmd_data + 1)) / (1 << 24);
        ALOGV("Current Volume (%f / %f ) new Volume (%f / %f)", context->left_vol,
              context->right_vol, left_vol, right_vol);

        context->left_vol = left_vol;
        context->right_vol = right_vol;

        // recompute gan dep cal level only if volume changed on speaker device
        if (recompute_gain_dep_cal_Level) {
            check_and_set_gain_dep_cal();
        }
    }
    break;

    default:
        ALOGW("volume_listener_command invalid command %d", cmd_code);
        status = -ENOSYS;
        break;
    }

exit:
    pthread_mutex_unlock(&vol_listner_init_lock);
    return status;
}

/* Effect Control Interface Implementation: get_descriptor */
static int vol_effect_get_descriptor(effect_handle_t   self,
                                     effect_descriptor_t *descriptor)
{
    vol_listener_context_t *context = (vol_listener_context_t *)self;
    ALOGV("%s Called ", __func__);

    if (descriptor == NULL) {
        ALOGE("%s: descriptor is NULL", __func__);
        return -EINVAL;
    }

    *descriptor = *context->desc;
    return 0;
}

static void init_once()
{
    int max_table_ent = 0;
    if (initialized) {
        ALOGV("%s : already init .. do nothing", __func__);
        return;
    }

    ALOGD("%s Called ", __func__);
    send_gain_dep_cal = NULL;
    get_custom_gain_table = NULL;

    pthread_mutex_init(&vol_listner_init_lock, NULL);

    // get hal function pointer
    if (access(PRIMARY_HAL_PATH, R_OK) == 0) {
        void *hal_lib_pointer = dlopen(PRIMARY_HAL_PATH, RTLD_NOW);
        if (hal_lib_pointer == NULL) {
            ALOGE("%s: DLOPEN failed for %s", __func__, PRIMARY_HAL_PATH);
        } else {
            ALOGV("%s: DLOPEN of %s Succes .. next get HAL entry function", __func__, PRIMARY_HAL_PATH);
            send_gain_dep_cal = (bool (*)(int))dlsym(hal_lib_pointer, AHAL_GAIN_DEPENDENT_INTERFACE_FUNCTION);
            if (send_gain_dep_cal == NULL) {
                ALOGE("Couldnt able to get the function symbol");
            }
            get_custom_gain_table = (int (*) (struct amp_db_and_gain_table *, int))dlsym(hal_lib_pointer, AHAL_GAIN_GET_MAPPING_TABLE);
            if (get_custom_gain_table == NULL) {
                ALOGE("Couldnt able to get the function AHAL_GAIN_GET_MAPPING_TABLE  symbol");
            } else {
                max_table_ent = get_custom_gain_table(volume_curve_gain_mapping_table, MAX_VOLUME_CAL_STEPS);
                // if number of entries is 0 use default
                // if number of entries > MAX_VOLUME_CAL_STEPS (this should never happen) then in this case
                // use only default number of steps but this will result in unexpected behaviour

                if (max_table_ent > 0 && max_table_ent <= MAX_VOLUME_CAL_STEPS) {
                    if (max_table_ent < total_volume_cal_step) {
                        for (int i = max_table_ent; i < total_volume_cal_step; i++ ) {
                            volume_curve_gain_mapping_table[i].amp = 0;
                            volume_curve_gain_mapping_table[i].db = 0;
                            volume_curve_gain_mapping_table[i].level = -1;
                        }
                    }
                    total_volume_cal_step = max_table_ent;
                    ALOGD("%s: using custome volume table", __func__);
                } else {
                    ALOGD("%s: using default volume table", __func__);
                }

                if (dumping_enabled) {
                    ALOGD("%s: dumping table here .. size of table received %d",
                           __func__, max_table_ent);
                    for (int i = 0; i < MAX_VOLUME_CAL_STEPS ; i++)
                        ALOGD("[%d]  %f %f %d", i, volume_curve_gain_mapping_table[i].amp,
                                                   volume_curve_gain_mapping_table[i].db,
                                                   volume_curve_gain_mapping_table[i].level);
                }
            }
        }
    } else {
        ALOGE("%s: not able to acces lib %s ", __func__, PRIMARY_HAL_PATH);
    }

    // check system property to see if dumping is required
    char check_dump_val[PROPERTY_VALUE_MAX];
    property_get("audio.volume.listener.dump", check_dump_val, "0");
    if (atoi(check_dump_val)) {
        dumping_enabled = true;
    }

    init_status = 0;
    list_init(&vol_effect_list);
    initialized = true;
}

static int lib_init()
{
    pthread_once(&once, init_once);
    ALOGV("%s Called ", __func__);
    return init_status;
}

static int vol_prc_lib_create(const effect_uuid_t *uuid,
                              int32_t session_id,
                              int32_t io_id __unused,
                              effect_handle_t *p_handle)
{
    int itt = 0;
    vol_listener_context_t *context = NULL;

    ALOGV("volume_prc_lib_create .. called ..");

    if (lib_init() != 0) {
        return init_status;
    }

    if (p_handle == NULL || uuid == NULL) {
        ALOGE("%s: %s is NULL", __func__, (p_handle == NULL) ? "p_handle" : "uuid");
        return -EINVAL;
    }

    context = (vol_listener_context_t *)calloc(1, sizeof(vol_listener_context_t));

    if (context == NULL) {
        ALOGE("%s: failed to allocate for context .. oops !!", __func__);
        return -EINVAL;
    }

    // check if UUID is supported
    for (itt = 0; descriptors[itt] != NULL; itt++) {
        if (memcmp(uuid, &descriptors[itt]->uuid, sizeof(effect_uuid_t)) == 0) {
            // check if this correct .. very imp
            context->desc = descriptors[itt];
            context->stream_type = itt;
            PRINT_STREAM_TYPE(itt)
            break;
        }
    }

    if (descriptors[itt] == NULL) {
        ALOGE("%s .. couldnt find passed uuid, something wrong", __func__);
        free(context);
        return -EINVAL;
    }

    ALOGV("%s CREATED_CONTEXT %p", __func__, context);

    context->itfe = &effect_interface;
    context->state = VOL_LISTENER_STATE_INITIALIZED;
    context->dev_id = AUDIO_DEVICE_NONE;
    context->session_id = session_id;

    // Add this to master list
    pthread_mutex_lock(&vol_listner_init_lock);
    list_add_tail(&vol_effect_list, &context->effect_list_node);

    if (dumping_enabled) {
        dump_list_l();
    }

    pthread_mutex_unlock(&vol_listner_init_lock);

    *p_handle = (effect_handle_t)context;
    return 0;
}

static int vol_prc_lib_release(effect_handle_t handle)
{
    struct listnode *node, *temp_node_next;
    vol_listener_context_t *context = NULL;
    vol_listener_context_t *recv_contex = (vol_listener_context_t *)handle;
    int status = -EINVAL;
    bool recompute_flag = false;
    int active_stream_count = 0;
    uint32_t session_id;
    uint32_t stream_type;
    effect_uuid_t uuid;

    ALOGV("%s context %p", __func__, handle);

    if (recv_contex == NULL) {
        return status;
    }
    pthread_mutex_lock(&vol_listner_init_lock);
    session_id = recv_contex->session_id;
    stream_type = recv_contex->stream_type;
    uuid = recv_contex->desc->uuid;

    // check if the handle/context provided is valid
    list_for_each_safe(node, temp_node_next, &vol_effect_list) {
        context = node_to_item(node, struct vol_listener_context_s, effect_list_node);
        if ((memcmp(&(context->desc->uuid), &uuid, sizeof(effect_uuid_t)) == 0)
            && (context->session_id == session_id)
            && (context->stream_type == stream_type)) {
            ALOGV("--- Found something to remove ---");
            list_remove(node);
            PRINT_STREAM_TYPE(context->stream_type);
            if (context->dev_id == AUDIO_DEVICE_OUT_SPEAKER) {
                recompute_flag = true;
            }
            free(context);
            status = 0;
        } else {
            ++active_stream_count;
        }
    }

    if (status != 0) {
        ALOGE("something wrong ... <<<--- Found NOTHING to remove ... ???? --->>>>>");
        pthread_mutex_unlock(&vol_listner_init_lock);
        return status;
    }

    // if there are no active streams, reset cal and volume level
    if (active_stream_count == 0) {
        current_gain_dep_cal_level = -1;
        current_vol = 0.0;
    }

    if (recompute_flag) {
        check_and_set_gain_dep_cal();
    }

    if (dumping_enabled) {
        dump_list_l();
    }
    pthread_mutex_unlock(&vol_listner_init_lock);
    return status;
}

static int vol_prc_lib_get_descriptor(const effect_uuid_t *uuid,
                                      effect_descriptor_t *descriptor)
{
    int i = 0;
    ALOGV("%s Called ", __func__);
    if (lib_init() != 0) {
        return init_status;
    }

    if (descriptor == NULL || uuid == NULL) {
        ALOGE("%s: %s is NULL", __func__, (descriptor == NULL) ? "descriptor" : "uuid");
        return -EINVAL;
    }

    for (i = 0; descriptors[i] != NULL; i++) {
        if (memcmp(uuid, &descriptors[i]->uuid, sizeof(effect_uuid_t)) == 0) {
            *descriptor = *descriptors[i];
            return 0;
        }
    }

    ALOGE("%s: couldnt found uuid passed, oops", __func__);
    return  -EINVAL;
}


/* effect_handle_t interface implementation for volume listener effect */
static const struct effect_interface_s effect_interface = {
    NULL,
    vol_effect_command,
    vol_effect_get_descriptor,
    NULL,
};

__attribute__((visibility("default")))
audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = {
    .tag = AUDIO_EFFECT_LIBRARY_TAG,
    .version = EFFECT_LIBRARY_API_VERSION,
    .name = "Volume Listener Effect Library",
    .implementor = "Qualcomm Technologies Inc.",
    .create_effect = vol_prc_lib_create,
    .release_effect = vol_prc_lib_release,
    .get_descriptor = vol_prc_lib_get_descriptor,
};
