/*
 * Copyright (c) 2013-2021, The Linux Foundation. All rights reserved.
 * Not a Contribution.
 *
 * Copyright (C) 2013 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.
 *
 * This file was modified by DTS, Inc. The portions of the
 * code modified by DTS, Inc are copyrighted and
 * licensed separately, as follows:
 *
 * (C) 2014 DTS, Inc.
 *
 * 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.
 *
 * Changes from Qualcomm Innovation Center are provided under the following license:
 *
 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
 * SPDX-License-Identifier: BSD-3-Clause-Clear
 */

#define LOG_TAG "AHAL: AudioDevice"
#define ATRACE_TAG (ATRACE_TAG_AUDIO|ATRACE_TAG_HAL)
#define AUDIO_CAPTURE_PERIOD_DURATION_MSEC 20
#define MIN_CHANNEL_COUNT 1
#define MAX_CHANNEL_COUNT 8

#include "AudioCommon.h"

#include "AudioDevice.h"

#include <dlfcn.h>
#include <inttypes.h>
#include <cutils/str_parms.h>

#include <vector>
#include <map>
#include<algorithm>

#include "PalApi.h"
#include "PalDefs.h"

#include <audio_extn/AudioExtn.h>
#include "audio_extn.h"
#include "battery_listener.h"

#define MIC_CHARACTERISTICS_XML_FILE "/vendor/etc/microphone_characteristics.xml"
static pal_device_id_t in_snd_device = PAL_DEVICE_NONE;
microphone_characteristics_t AudioDevice::microphones;
snd_device_to_mic_map_t AudioDevice::microphone_maps[PAL_MAX_INPUT_DEVICES];
bool AudioDevice::mic_characteristics_available = false;

card_status_t AudioDevice::sndCardState = CARD_STATUS_ONLINE;

btsco_lc3_cfg_t AudioDevice::btsco_lc3_cfg = {};

struct audio_string_to_enum {
    const char* name;
    unsigned int value;
};

static const struct audio_string_to_enum mic_locations[AUDIO_MICROPHONE_LOCATION_CNT] = {
    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_LOCATION_UNKNOWN),
    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_LOCATION_MAINBODY),
    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_LOCATION_MAINBODY_MOVABLE),
    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_LOCATION_PERIPHERAL),
};

static const struct audio_string_to_enum mic_directionalities[AUDIO_MICROPHONE_DIRECTIONALITY_CNT] = {
    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_DIRECTIONALITY_OMNI),
    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_DIRECTIONALITY_BI_DIRECTIONAL),
    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_DIRECTIONALITY_UNKNOWN),
    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_DIRECTIONALITY_CARDIOID),
    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_DIRECTIONALITY_HYPER_CARDIOID),
    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_DIRECTIONALITY_SUPER_CARDIOID),
};

static const struct audio_string_to_enum mic_channel_mapping[AUDIO_MICROPHONE_CHANNEL_MAPPING_CNT] = {
    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED),
    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_CHANNEL_MAPPING_DIRECT),
    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED),
};

static const struct audio_string_to_enum device_in_types[] = {
    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_AMBIENT),
    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_COMMUNICATION),
    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BUILTIN_MIC),
    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET),
    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_WIRED_HEADSET),
    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_AUX_DIGITAL),
    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_HDMI),
    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_VOICE_CALL),
    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_TELEPHONY_RX),
    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BACK_MIC),
    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_REMOTE_SUBMIX),
    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET),
    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET),
    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_USB_ACCESSORY),
    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_USB_DEVICE),
    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_FM_TUNER),
    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_TV_TUNER),
    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_LINE),
    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_SPDIF),
    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_A2DP),
    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BLE_HEADSET),
    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_LOOPBACK),
    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_IP),
    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BUS),
    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_PROXY),
    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_USB_HEADSET),
    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_BLE),
    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_DEFAULT),
    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_ECHO_REFERENCE),
};

enum {
    AUDIO_MICROPHONE_CHARACTERISTIC_NONE = 0u, // 0x0
    AUDIO_MICROPHONE_CHARACTERISTIC_SENSITIVITY = 1u, // 0x1
    AUDIO_MICROPHONE_CHARACTERISTIC_MAX_SPL = 2u, // 0x2
    AUDIO_MICROPHONE_CHARACTERISTIC_MIN_SPL = 4u, // 0x4
    AUDIO_MICROPHONE_CHARACTERISTIC_ORIENTATION = 8u, // 0x8
    AUDIO_MICROPHONE_CHARACTERISTIC_GEOMETRIC_LOCATION = 16u, // 0x10
    AUDIO_MICROPHONE_CHARACTERISTIC_ALL = 31u, /* ((((SENSITIVITY | MAX_SPL) | MIN_SPL)
                                                  | ORIENTATION) | GEOMETRIC_LOCATION) */
};

static bool hdr_set_parameters(std::shared_ptr<AudioDevice> adev,
    struct str_parms *parms) {

    if (adev == nullptr || parms == nullptr) {
        AHAL_ERR("%s Invalid arguments", __func__);
        return false;
    }

    int ret = 0, val = 0;
    char value[32];
    bool changes = false;

    /* HDR Audio Parameters */
    ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_HDR, value,
              sizeof(value));
    if (ret >= 0) {
        if (strncmp(value, "true", 4) == 0)
            adev->hdr_record_enabled = true;
        else
            adev->hdr_record_enabled = false;

        changes = true;
        AHAL_INFO("HDR Enabled: %d", adev->hdr_record_enabled);
    }

    ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_WNR, value,
              sizeof(value));
    if (ret >= 0) {
        if (strncmp(value, "true", 4) == 0)
            adev->wnr_enabled = true;
        else
            adev->wnr_enabled = false;

        AHAL_INFO("WNR Enabled: %d", adev->wnr_enabled);
    }

    ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_ANS, value,
              sizeof(value));
    if (ret >= 0) {
        if (strncmp(value, "true", 4) == 0)
            adev->ans_enabled = true;
        else
            adev->ans_enabled = false;

        AHAL_INFO("ANS Enabled: %d", adev->ans_enabled);
    }

    /* Checking for Device rotation */
    ret = str_parms_get_int(parms, AUDIO_PARAMETER_KEY_ROTATION, &val);
    if (ret >= 0) {
        adev->inverted = (val == ROTATION_270 || val == ROTATION_180)? true : false;
        adev->orientation_landscape = (val == ROTATION_90 || val == ROTATION_270)? true : false;
        changes = true;
        AHAL_INFO("orientation_landscape is %d and inverted is %d", adev->orientation_landscape,
            adev->inverted);
    }

    ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_ORIENTATION, value,
              sizeof(value));
    if (ret >= 0) {
        if (strncmp(value, "landscape", 9) == 0)
            adev->orientation_landscape = true;
        else if (strncmp(value, "portrait", 8) == 0)
            adev->orientation_landscape = false;

        changes = true;
        AHAL_INFO("Orientation %s",
            adev->orientation_landscape ? "landscape" : "portrait");
    }

    ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_INVERTED, value,
              sizeof(value));
    if (ret >= 0) {
        if (strncmp(value, "true", 4) == 0)
            adev->inverted = true;
        else
            adev->inverted = false;

        changes = true;
        AHAL_INFO("Orientation inverted: %d", adev->inverted);
    }

    ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_FACING, value,
              sizeof(value));
    if (ret >= 0) {
        /*0-none, 1-back, 2-front/selfie*/
        if (strncmp(value, "front", 5) == 0)
            adev->facing = 2;
        else if (strncmp(value, "back", 4) == 0)
            adev->facing = 1;
        else if (strncmp(value, "none", 4) == 0)
            adev->facing = 0;

        changes = true;
        AHAL_INFO("Device facing %s", value);
    }

    ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_HDR_CHANNELS, value,
              sizeof(value));
    if (ret >= 0) {
        val = atoi(value);
        if (val != 4) {
           AHAL_DBG("Invalid HDR channels: %d", val);
        } else {
            adev->hdr_channel_count = val;
        }
    }

    ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_HDR_SAMPLERATE, value,
              sizeof(value));
    if (ret >= 0) {
        val = atoi(value);
        if (val != 48000) {
            AHAL_DBG("Invalid HDR sample rate: %d", val);
        } else {
            adev->hdr_sample_rate = val;
        }
    }

    return changes;
}

static void hdr_get_parameters(std::shared_ptr<AudioDevice> adev,
    struct str_parms *query, struct str_parms *reply) {

    if (adev == nullptr || query == nullptr || reply == nullptr) {
        AHAL_ERR("%s Invalid arguments", __func__);
        return;
    }

    int32_t ret;
    char value[256]={0};
    size_t size = 0;

    /* HDR Audio Parameters */
    ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_HDR, value,
              sizeof(value));
    if (ret >= 0) {
        str_parms_add_str(reply, AUDIO_PARAMETER_KEY_HDR,
            adev->hdr_record_enabled ? "true" : "false");
        AHAL_VERBOSE("%s=%s", AUDIO_PARAMETER_KEY_HDR,
            adev->hdr_record_enabled ? "true" : "false");
    }

    ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_WNR, value,
              sizeof(value));
    if (ret >= 0) {
        str_parms_add_str(reply, AUDIO_PARAMETER_KEY_WNR, adev->wnr_enabled
            ? "true" : "false");
        AHAL_VERBOSE("%s=%s", AUDIO_PARAMETER_KEY_WNR, adev->wnr_enabled
            ? "true" : "false");
    }

    ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_ANS, value,
              sizeof(value));
    if (ret >= 0) {
        str_parms_add_str(reply, AUDIO_PARAMETER_KEY_ANS, adev->ans_enabled
            ? "true" : "false");
        AHAL_VERBOSE("%s=%s", AUDIO_PARAMETER_KEY_ANS, adev->ans_enabled
            ? "true" : "false");
    }

    ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_ORIENTATION, value,
              sizeof(value));
    if (ret >= 0) {
        str_parms_add_str(reply,AUDIO_PARAMETER_KEY_ORIENTATION,
            adev->orientation_landscape ? "landscape" : "portrait");
        AHAL_VERBOSE("%s=%s", AUDIO_PARAMETER_KEY_ORIENTATION,
            adev->orientation_landscape ? "landscape" : "portrait");
    }

    ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_INVERTED, value,
              sizeof(value));
    if (ret >= 0) {
        str_parms_add_str(reply, AUDIO_PARAMETER_KEY_INVERTED, adev->inverted
            ? "true" : "false");
        AHAL_VERBOSE("%s=%s", AUDIO_PARAMETER_KEY_INVERTED, adev->inverted
            ? "true" : "false");
    }

    ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_FACING, value,
              sizeof(value));
    if (ret >= 0) {
        str_parms_add_str(reply, AUDIO_PARAMETER_KEY_FACING,
            (adev->facing == 0) ? "none" : ((adev->facing == 1) ?  "back"
                : "front"));
        AHAL_VERBOSE("%s=%s", AUDIO_PARAMETER_KEY_FACING, (adev->facing == 0)
            ? "none" : ((adev->facing == 1) ?  "back" : "front"));
    }

    ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_HDR_CHANNELS, value,
              sizeof(value));
    if (ret >= 0) {
        str_parms_add_int(reply, AUDIO_PARAMETER_KEY_HDR_CHANNELS,
            adev->hdr_channel_count);
        AHAL_VERBOSE("%s=%d",AUDIO_PARAMETER_KEY_HDR_CHANNELS,
            adev->hdr_channel_count);
    }

    ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_HDR_SAMPLERATE, value,
              sizeof(value));
    if (ret >= 0) {
        str_parms_add_int(reply, AUDIO_PARAMETER_KEY_HDR_SAMPLERATE,
            adev->hdr_sample_rate);
        AHAL_INFO("%s=%d", AUDIO_PARAMETER_KEY_HDR_SAMPLERATE, adev->hdr_sample_rate);
    }
}

AudioDevice::~AudioDevice() {
    audio_extn_gef_deinit(adev_);
    audio_extn_sound_trigger_deinit(adev_);
    AudioExtn::battery_properties_listener_deinit();
    pal_deinit();
}


std::shared_ptr<AudioDevice> AudioDevice::GetInstance() {
    if (!adev_) {
        adev_ = std::shared_ptr<AudioDevice> (new AudioDevice());
        device_ = std::shared_ptr<audio_hw_device_t> (new audio_hw_device_t());
    }

    return adev_;
}

std::shared_ptr<AudioDevice> AudioDevice::GetInstance(audio_hw_device_t* device) {
    if (device == (audio_hw_device_t*)device_.get())
        return AudioDevice::adev_;
    else
        return NULL;
}

std::shared_ptr<StreamOutPrimary> AudioDevice::CreateStreamOut(
                        audio_io_handle_t handle,
                        const std::set<audio_devices_t>& devices,
                        audio_output_flags_t flags,
                        struct audio_config *config,
                        audio_stream_out **stream_out,
                        const char *address) {
    std::shared_ptr<StreamOutPrimary> astream = nullptr;

    try {
        astream = std::shared_ptr<StreamOutPrimary> (new StreamOutPrimary(handle,
                                       devices, flags, config, address,
                                       fnp_offload_effect_start_output_,
                                       fnp_offload_effect_stop_output_,
                                       fnp_visualizer_start_output_,
                                       fnp_visualizer_stop_output_));
    } catch (const std::exception& e) {
        AHAL_ERR("Failed to create StreamOutPrimary");
        return nullptr;
    }
    astream->GetStreamHandle(stream_out);
    out_list_mutex.lock();
    stream_out_list_.push_back(astream);
    AHAL_DBG("output stream %d %p",(int)stream_out_list_.size(), stream_out);
    if (flags & AUDIO_OUTPUT_FLAG_PRIMARY) {
        if (voice_)
            voice_->stream_out_primary_ = astream;
    }
    out_list_mutex.unlock();
    return astream;
}

void AudioDevice::CloseStreamOut(std::shared_ptr<StreamOutPrimary> stream) {
    out_list_mutex.lock();
    auto iter =
        std::find(stream_out_list_.begin(), stream_out_list_.end(), stream);
    if (iter == stream_out_list_.end()) {
        AHAL_ERR("invalid output stream");
    } else {
        stream_out_list_.erase(iter);
    }
    out_list_mutex.unlock();
}

int AudioDevice::CreateAudioPatch(audio_patch_handle_t *handle,
                                  const std::vector<struct audio_port_config>& sources,
                                  const std::vector<struct audio_port_config>& sinks) {
    int ret = 0;
    bool new_patch = false;
    AudioPatch *patch = NULL;
    std::shared_ptr<StreamPrimary> stream = nullptr;
    AudioPatch::PatchType patch_type = AudioPatch::PATCH_NONE;
    audio_io_handle_t io_handle = AUDIO_IO_HANDLE_NONE;
    audio_source_t input_source = AUDIO_SOURCE_DEFAULT;
    std::set<audio_devices_t> device_types;

    AHAL_DBG("enter: num sources %zu, num_sinks %zu", sources.size(), sinks.size());

    if (!handle || sources.empty() || sources.size() > AUDIO_PATCH_PORTS_MAX ||
        sinks.empty() || sinks.size() > AUDIO_PATCH_PORTS_MAX) {
        AHAL_ERR("Invalid patch arguments");
        ret = -EINVAL;
        goto exit;
    }

    if (sources.size() > 1) {
        AHAL_ERR("error multiple sources are not supported");
        ret = -EINVAL;
        goto exit;
    }

    AHAL_DBG("source role %d, source type %d", sources[0].role, sources[0].type);

    // Populate source/sink information and fetch stream info
    switch (sources[0].type) {
        case AUDIO_PORT_TYPE_DEVICE: // Patch for audio capture or loopback
            device_types.insert(sources[0].ext.device.type);
            if (sinks[0].type == AUDIO_PORT_TYPE_MIX) {
                io_handle = sinks[0].ext.mix.handle;
                input_source = sinks[0].ext.mix.usecase.source;
                patch_type = AudioPatch::PATCH_CAPTURE;
                AHAL_DBG("Capture patch from device %x to mix %d",
                          sources[0].ext.device.type, sinks[0].ext.mix.handle);
            } else {
                /*Device to device patch is not implemented.
                  This space will need changes if audio HAL
                  handles device to device patches in the future.*/
                patch_type = AudioPatch::PATCH_DEVICE_LOOPBACK;
                AHAL_ERR("error device to device patches not supported");
                ret = -ENOSYS;
                goto exit;
            }
            break;
        case AUDIO_PORT_TYPE_MIX: // Patch for audio playback
            io_handle = sources[0].ext.mix.handle;
            for (const auto &sink : sinks)
               device_types.insert(sink.ext.device.type);
            patch_type = AudioPatch::PATCH_PLAYBACK;
            AHAL_DBG("Playback patch from mix handle %d to device %x",
                  io_handle, AudioExtn::get_device_types(device_types));
            break;
        case AUDIO_PORT_TYPE_SESSION:
        case AUDIO_PORT_TYPE_NONE:
            AHAL_ERR("Unsupported source type %d", sources[0].type);
            ret = -EINVAL;
            goto exit;
    }

    if (patch_type == AudioPatch::PATCH_PLAYBACK)
        stream = OutGetStream(io_handle);
    else
        stream = InGetStream(io_handle);

    if(!stream) {
        AHAL_ERR("Failed to fetch stream with io handle %d", io_handle);
        ret = -EINVAL;
        goto exit;
    }

    // empty patch...generate new handle
    if (*handle == AUDIO_PATCH_HANDLE_NONE) {
        patch = new AudioPatch(patch_type, sources, sinks);
        *handle = patch->handle;
        new_patch = true;
    } else {
        std::lock_guard<std::mutex> lock(patch_map_mutex);
        auto it = patch_map_.find(*handle);
        if (it == patch_map_.end()) {
            AHAL_ERR("Unable to fetch patch with handle %d", *handle);
            ret = -EINVAL;
            goto exit;
        }
        patch = &(*it->second);
        patch->type = patch_type;
        patch->sources = sources;
        patch->sinks = sinks;
    }

    if (voice_ && patch_type == AudioPatch::PATCH_PLAYBACK)
        ret = voice_->RouteStream(device_types);
    ret |= stream->RouteStream(device_types);

    if (ret) {
        if (new_patch)
            delete patch;
        AHAL_ERR("Stream routing failed for io_handle %d", io_handle);
    } else if (new_patch) {
        // new patch...add to patch map
        std::lock_guard<std::mutex> lock(patch_map_mutex);
        patch_map_[patch->handle] = patch;
        AHAL_DBG("Added a new patch with handle %d", patch->handle);
    }
exit:
    AHAL_DBG("Exit ret: %d", ret);
    return ret;
}

int AudioDevice::ReleaseAudioPatch(audio_patch_handle_t handle) {
    int ret = 0;
    AudioPatch *patch = NULL;
    std::shared_ptr<StreamPrimary> stream = nullptr;
    audio_io_handle_t io_handle = AUDIO_IO_HANDLE_NONE;
    AudioPatch::PatchType patch_type = AudioPatch::PATCH_NONE;

    AHAL_DBG("Release patch with handle %d", handle);

    if (handle == AUDIO_PATCH_HANDLE_NONE) {
        AHAL_ERR("Invalid patch handle %d", handle);
        return -EINVAL;
    }

    // grab the io_handle from the patch
    patch_map_mutex.lock();
    auto patch_it = patch_map_.find(handle);
    if (patch_it == patch_map_.end() || !patch_it->second) {
        AHAL_ERR("error patch info not found with handle %d", handle);
        patch_map_mutex.unlock();
        return -EINVAL;
    }
    patch = &(*patch_it->second);
    patch_type = patch->type;
    switch (patch->sources[0].type) {
        case AUDIO_PORT_TYPE_MIX:
            io_handle = patch->sources[0].ext.mix.handle;
            break;
        case AUDIO_PORT_TYPE_DEVICE:
            if (patch->type == AudioPatch::PATCH_CAPTURE)
                io_handle = patch->sinks[0].ext.mix.handle;
            break;
        case AUDIO_PORT_TYPE_SESSION:
        case AUDIO_PORT_TYPE_NONE:
            AHAL_DBG("Invalid port type: %d", patch->sources[0].type);
            patch_map_mutex.unlock();
            return -EINVAL;
    }
    patch_map_mutex.unlock();

    if (patch_type == AudioPatch::PATCH_PLAYBACK)
        stream = OutGetStream(io_handle);
    else
        stream = InGetStream(io_handle);

    if (!stream) {
        AHAL_ERR("Failed to fetch stream with io handle %d", io_handle);
        return -EINVAL;
    }

    ret = stream->RouteStream({AUDIO_DEVICE_NONE});

    if (ret)
        AHAL_ERR("Stream routing failed for io_handle %d", io_handle);

    std::lock_guard lock(patch_map_mutex);
    patch_map_.erase(handle);
    delete patch;

    AHAL_DBG("Successfully released patch %d", handle);
    return ret;
}

std::shared_ptr<StreamInPrimary> AudioDevice::CreateStreamIn(
                                        audio_io_handle_t handle,
                                        const std::set<audio_devices_t>& devices,
                                        audio_input_flags_t flags,
                                        struct audio_config *config,
                                        const char *address,
                                        audio_stream_in **stream_in,
                                        audio_source_t source) {
    std::shared_ptr<StreamInPrimary> astream (new StreamInPrimary(handle,
                                              devices, flags, config,
                                              address, source));
    astream->GetStreamHandle(stream_in);
    in_list_mutex.lock();
    stream_in_list_.push_back(astream);
    in_list_mutex.unlock();
    AHAL_DBG("input stream %d %p",(int)stream_in_list_.size(), stream_in);
    if (voice_) {
        voice_->stream_in_primary_ = astream;
    }
    return astream;
}

void AudioDevice::CloseStreamIn(std::shared_ptr<StreamInPrimary> stream) {
    in_list_mutex.lock();
    auto iter =
        std::find(stream_in_list_.begin(), stream_in_list_.end(), stream);
    if (iter == stream_in_list_.end()) {
        AHAL_ERR("invalid input stream");
    } else {
        stream_in_list_.erase(iter);
        if (voice_) {
            if (stream_in_list_.size() == 0) {
                voice_->stream_in_primary_ = nullptr;
            } else {
                voice_->stream_in_primary_ = stream_in_list_[0];
            }
        }
    }
    in_list_mutex.unlock();
}

static int adev_close(hw_device_t *device __unused) {
    return 0;
}

static int adev_init_check(const struct audio_hw_device *dev __unused) {
    return 0;
}

void adev_on_battery_status_changed(bool charging)
{
    std::shared_ptr<AudioDevice>adevice = AudioDevice::GetInstance();
    AHAL_DBG("battery status changed to %scharging",
             charging ? "" : "not ");
    adevice->SetChargingMode(charging);
}

static int adev_set_voice_volume(struct audio_hw_device *dev, float volume) {
    std::shared_ptr<AudioDevice>adevice = AudioDevice::GetInstance(dev);
    if (!adevice) {
        AHAL_ERR("invalid adevice object");
        return -EINVAL;
    }

    return adevice->SetVoiceVolume(volume);
}

static int adev_pal_global_callback(uint32_t event_id, uint32_t *event_data,
                                     uint64_t cookie) {
    AHAL_DBG("event_id (%d), event_data (%d), cookie %" PRIu64,
              event_id, *event_data, cookie);
    switch (event_id) {
    case PAL_SND_CARD_STATE :
        AudioDevice::sndCardState = (card_status_t)*event_data;
        AHAL_DBG("sound card status changed %d sndCardState %d",
              *event_data, AudioDevice::sndCardState);
        break;
    default :
       AHAL_ERR("Invalid event id:%d", event_id);
       return -EINVAL;
    }
    return 0;
}

static int adev_open_output_stream(struct audio_hw_device *dev,
                            audio_io_handle_t handle,
                            audio_devices_t devices,
                            audio_output_flags_t flags,
                            struct audio_config *config,
                            struct audio_stream_out **stream_out,
                            const char *address) {
    int32_t ret = 0;
    std::shared_ptr<StreamOutPrimary> astream;

    AHAL_DBG("enter: format(%#x) sample_rate(%d) channel_mask(%#x) devices(%#x)\
        flags(%#x) address(%s)", config->format, config->sample_rate,
        config->channel_mask, devices, flags, address);

    std::shared_ptr<AudioDevice>adevice = AudioDevice::GetInstance(dev);
    if (!adevice) {
        AHAL_ERR("invalid adevice object");
        goto exit;
    }

    /* This check is added for oflload streams, so that
     * flinger will fallback to DB stream during SSR.
     */
    if (AudioDevice::sndCardState == CARD_STATUS_OFFLINE &&
        (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD ||
        flags & AUDIO_OUTPUT_FLAG_DIRECT)) {
        AHAL_ERR("error: sound card offline");
        ret = -ENODEV;
        goto exit;
    }
    /* On error AAudioService will retry with supported format passed
     */
    if ((flags & AUDIO_OUTPUT_FLAG_MMAP_NOIRQ) &&
        config->format == AUDIO_FORMAT_PCM_FLOAT) {
        AHAL_ERR("unsupported format: %#x", config->format);
        ret = -EINVAL;
        goto exit;
    }

    astream = adevice->OutGetStream(handle);
    if (astream == nullptr) {
        astream = adevice->CreateStreamOut(handle, {devices}, flags, config, stream_out, address);
        if (astream == nullptr) {
            ret = -ENOMEM;
            goto exit;
        }
    }
exit:
    AHAL_DBG("Exit ret: %d", ret);
    return ret;
}

void adev_close_output_stream(struct audio_hw_device *dev,
                              struct audio_stream_out *stream) {
    std::shared_ptr<StreamOutPrimary> astream_out;
    std::shared_ptr<AudioDevice> adevice = AudioDevice::GetInstance(dev);
    if (!adevice) {
        AHAL_ERR("invalid adevice object");
        return;
    }

    astream_out = adevice->OutGetStream((audio_stream_t*)stream);
    if (!astream_out) {
        AHAL_ERR("invalid astream_in object");
        return;
    }

    AHAL_DBG("Enter:stream_handle(%p)", astream_out.get());

    adevice->CloseStreamOut(astream_out);

    AHAL_DBG("Exit");
}

void adev_close_input_stream(struct audio_hw_device *dev,
                             struct audio_stream_in *stream)
{
    std::shared_ptr<StreamInPrimary> astream_in;
    std::shared_ptr<AudioDevice> adevice = AudioDevice::GetInstance(dev);
    if (!adevice) {
        AHAL_ERR("invalid adevice object");
        return;
    }

    astream_in = adevice->InGetStream((audio_stream_t*)stream);
    if (!astream_in) {
        AHAL_ERR("invalid astream_in object");
        return;
    }

    AHAL_DBG("Enter:stream_handle(%p)", astream_in.get());

    adevice->CloseStreamIn(astream_in);

    AHAL_DBG("Exit");
}

/*
 *  Add 24bit recording support for MIC, CAMCORDER, UNPROCESSED input sources.
*/
static int audio_source_supports_24bit_record(audio_source_t source) {
    switch(source) {
        case AUDIO_SOURCE_MIC:
        case AUDIO_SOURCE_CAMCORDER:
        case AUDIO_SOURCE_UNPROCESSED:
        case AUDIO_SOURCE_VOICE_RECOGNITION:
            return true;
        default:
            return false;
    }
}

static int adev_open_input_stream(struct audio_hw_device *dev,
                                  audio_io_handle_t handle,
                                  audio_devices_t devices,
                                  struct audio_config *config,
                                  struct audio_stream_in **stream_in,
                                  audio_input_flags_t flags,
                                  const char *address,
                                  audio_source_t source) {
    int32_t ret = 0;
    std::shared_ptr<StreamInPrimary> astream = nullptr;
    audio_format_t inputFormat = config->format;
    AHAL_DBG("enter: sample_rate(%d) channel_mask(%#x) devices(%#x)\
        io_handle(%d) source(%d) format %x", config->sample_rate,
        config->channel_mask, devices, handle, source, config->format);

    std::shared_ptr<AudioDevice>adevice = AudioDevice::GetInstance(dev);
    if (!adevice) {
        AHAL_ERR("invalid adevice object");
        goto exit;
    }

    /*  In case of any source requesting 32 bit or float return error
     *  indicating format supported is up to 24 bit only.
     *  On error AudioFlinger will retry with supported format passed.
     */
    if (config->format == AUDIO_FORMAT_PCM_FLOAT ||
        config->format == AUDIO_FORMAT_PCM_32_BIT) {
        config->format = AUDIO_FORMAT_PCM_24_BIT_PACKED;
        ret = -EINVAL;
    }

    switch (config->format) {
        case AUDIO_FORMAT_PCM_24_BIT_PACKED:
        case AUDIO_FORMAT_PCM_8_24_BIT:
            if (audio_source_supports_24bit_record(source)) {
                AHAL_DBG("set format %d for input source %d", config->format, source);
            } else {
                config->format = AUDIO_FORMAT_PCM_16_BIT;
                ret = -EINVAL;
            }
            break;
        default:
            break;
    }

    if (ret != 0) {
        AHAL_ERR("unsupported input format %d, fallback format %d input source %d", inputFormat,
                config->format, source);
        if (config->sample_rate > 48000)
            config->sample_rate = 48000;
        goto exit;
    }


    astream = adevice->InGetStream(handle);
    if (astream == nullptr)
        astream = adevice->CreateStreamIn(handle, {devices}, flags, config,
                address, stream_in, source);

  exit:
      AHAL_DBG("Exit ret: %d", ret);
      return ret;
}

static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
{
    std::shared_ptr<AudioDevice>adevice = AudioDevice::GetInstance(dev);
    if (!adevice) {
        AHAL_ERR("invalid adevice object");
        return -EINVAL;
    }

    return adevice->SetMode(mode);
}

static int adev_set_mic_mute(struct audio_hw_device *dev, bool state) {
    std::shared_ptr<AudioDevice> adevice = AudioDevice::GetInstance(dev);
    if (!adevice) {
        AHAL_ERR("invalid adevice object");
        return -EINVAL;
    }

    return adevice->SetMicMute(state);
}

static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state) {
    std::shared_ptr<AudioDevice> adevice =
        AudioDevice::GetInstance((audio_hw_device_t *)dev);
    if (!adevice) {
        AHAL_ERR("invalid adevice object");
        return -EINVAL;
    }

    return adevice->GetMicMute(state);
}

static int adev_set_master_volume(struct audio_hw_device *dev __unused,
                                  float volume __unused) {
    return -ENOSYS;
}

static int adev_get_master_volume(struct audio_hw_device *dev __unused,
                                  float *volume __unused) {
    return -ENOSYS;
}

static int adev_set_master_mute(struct audio_hw_device *dev __unused,
                                bool muted __unused) {
    return -ENOSYS;
}

static int adev_get_master_mute(struct audio_hw_device *dev __unused,
                                bool *muted __unused) {
    return -ENOSYS;
}

static int adev_set_parameters(struct audio_hw_device *dev,
                               const char *kvpairs) {
    std::shared_ptr<AudioDevice> adevice = AudioDevice::GetInstance(dev);
    if (!adevice) {
        AHAL_ERR("invalid adevice object");
        return -EINVAL;
    }

    return adevice->SetParameters(kvpairs);
}

static char* adev_get_parameters(const struct audio_hw_device *dev,
                                 const char *keys) {
    std::shared_ptr<AudioDevice> adevice =
        AudioDevice::GetInstance((audio_hw_device_t*)dev);
    if (!adevice) {
        AHAL_ERR("invalid adevice object");
        return NULL;
    }

    return adevice->GetParameters(keys);
}

static int check_input_parameters(uint32_t sample_rate,
                                  audio_format_t format,
                                  int channel_count)
{

    int ret = 0;
    static std::vector<int> channel_counts_supported = {1,2,3,4,6,8,10,12,14};
    static std::vector<uint32_t> sample_rate_supported = {8000,11025,12000,16000,
                                                    22050,24000,32000,44100,48000,
                                                    88200,96000,176400,192000 };

    if (((format != AUDIO_FORMAT_PCM_16_BIT) && (format != AUDIO_FORMAT_PCM_8_24_BIT) &&
        (format != AUDIO_FORMAT_PCM_24_BIT_PACKED) && (format != AUDIO_FORMAT_PCM_32_BIT) &&
        (format != AUDIO_FORMAT_PCM_FLOAT))) {
            AHAL_ERR("format not supported!!! format:%d", format);
            return -EINVAL;
    }

    if ((channel_count < MIN_CHANNEL_COUNT) || (channel_count > MAX_CHANNEL_COUNT)) {
        ALOGE("%s: unsupported channel count (%d) passed  Min / Max (%d / %d)", __func__,
                channel_count, MIN_CHANNEL_COUNT, MAX_CHANNEL_COUNT);
        return -EINVAL;
    }

    if ( std::find(channel_counts_supported.begin(),
                   channel_counts_supported.end(),
                   channel_count) == channel_counts_supported.end() ) {
        AHAL_ERR("channel count not supported!!! chanel count:%d", channel_count);
        return -EINVAL;
    }

    if ( std::find(sample_rate_supported.begin(), sample_rate_supported.end(),
                   sample_rate) == sample_rate_supported.end() ) {
        AHAL_ERR("sample rate not supported!!! sample_rate:%d", sample_rate);
        return -EINVAL;
    }

    return ret;
 }

static size_t adev_get_input_buffer_size(
                                const struct audio_hw_device *dev __unused,
                                const struct audio_config *config ) {

    size_t size = 0;
    uint32_t bytes_per_period_sample = 0;

    /* input for compress formats */
    if (config && !audio_is_linear_pcm(config->format)) {
        if (config->format == AUDIO_FORMAT_AAC_LC) {
            return COMPRESS_CAPTURE_AAC_MAX_OUTPUT_BUFFER_SIZE;
        }
        return 0;
    }

    if (config != NULL) {
        int channel_count = audio_channel_count_from_in_mask(config->channel_mask);

        /* Don't know if USB HIFI in this context so use true to be conservative */
        if (check_input_parameters(config->sample_rate, config->format, channel_count) != 0) {
            AHAL_ERR("input parameters not supported!!!");
            return 0;
        }

        size = (config->sample_rate * AUDIO_CAPTURE_PERIOD_DURATION_MSEC) / 1000;
        bytes_per_period_sample = audio_bytes_per_sample(config->format) * channel_count;
        size *= bytes_per_period_sample;
    }
         /* make sure the size is multiple of 32 bytes and additionally multiple of
          * the frame_size (required for 24bit samples and non-power-of-2 channel counts)
          * At 48 kHz mono 16-bit PCM:
          *  5.000 ms = 240 frames = 15*16*1*2 = 480, a whole multiple of 32 (15)
          *  3.333 ms = 160 frames = 10*16*1*2 = 320, a whole multiple of 32 (10)
          * Also, make sure the size is multiple of bytes per period sample
          */
    size = nearest_multiple(size, lcm(32, bytes_per_period_sample));

    return size;

}

int adev_release_audio_patch(struct audio_hw_device *dev,
                             audio_patch_handle_t handle) {
    std::shared_ptr<AudioDevice> adevice = AudioDevice::GetInstance(dev);
    if (!adevice) {
        AHAL_ERR("GetInstance() failed");
        return -EINVAL;
    }
    return adevice->ReleaseAudioPatch(handle);
}

int adev_create_audio_patch(struct audio_hw_device *dev,
                            unsigned int num_sources,
                            const struct audio_port_config *sources,
                            unsigned int num_sinks,
                            const struct audio_port_config *sinks,
                            audio_patch_handle_t *handle) {

    if (!handle) {
        AHAL_ERR("Invalid handle");
        return -EINVAL;
    }

    std::shared_ptr<AudioDevice> adevice = AudioDevice::GetInstance(dev);
    if (!adevice) {
        AHAL_ERR("GetInstance() failed");
        return -EINVAL;
    }

    std::vector<struct audio_port_config> source_vec(sources, sources + num_sources);
    std::vector<struct audio_port_config> sink_vec(sinks, sinks + num_sinks);

    return adevice->CreateAudioPatch(handle, source_vec, sink_vec);
}

int get_audio_port_v7(struct audio_hw_device *dev, struct audio_port_v7 *config) {
    std::ignore = dev;
    std::ignore = config;

    return 0;
}

int adev_set_device_connected_state_v7(struct audio_hw_device *dev,
                                        struct audio_port_v7 *port,
                                        bool connected) {
    std::ignore = dev;
    std::ignore = port;
    std::ignore = connected;
    return -ENOSYS;
}

int adev_set_audio_port_config(struct audio_hw_device *dev,
                               const struct audio_port_config *config)
{
    std::ignore = dev;
    std::ignore = config;

    return 0;
}

static int adev_dump(const audio_hw_device_t *device, int fd)
{
    dprintf(fd, " \n");
    dprintf(fd, "PrimaryHal adev: \n");
    int major =  (device->common.version >> 8) & 0xff;
    int minor =   device->common.version & 0xff;
    dprintf(fd, "Device API Version: %d.%d \n", major, minor);

#ifdef PAL_HIDL_ENABLED
    dprintf(fd, "PAL HIDL enabled");
#else
    dprintf(fd, "PAL HIDL disabled");
#endif

    return 0;
}

static int adev_get_microphones(const struct audio_hw_device *dev __unused,
                struct audio_microphone_characteristic_t *mic_array,
                size_t *mic_count) {
    return AudioDevice::get_microphones(mic_array, mic_count);
}

int AudioDevice::Init(hw_device_t **device, const hw_module_t *module) {
    int ret = 0;
    bool is_charging = false;

    /*
     * register HIDL services for PAL & AGM
     * pal_init() depends on AGM, so need to initialize
     * hidl interface before calling to pal_init()
     */
    ret = AudioExtn::audio_extn_hidl_init();
    if (ret) {
        AHAL_ERR("audio_extn_hidl_init failed ret=(%d)", ret);
        return ret;
    }

    ret = pal_init();
    if (ret) {
        AHAL_ERR("pal_init failed ret=(%d)", ret);
        return -EINVAL;
    }

    ret = pal_register_global_callback(&adev_pal_global_callback, (uint64_t)this);
    if (ret) {
        AHAL_ERR("pal register callback failed ret=(%d)", ret);
    }

    adev_->device_.get()->common.tag = HARDWARE_DEVICE_TAG;
    adev_->device_.get()->common.version = AUDIO_DEVICE_API_VERSION_3_2;
    adev_->device_.get()->common.close = adev_close;
    adev_->device_.get()->init_check = adev_init_check;
    adev_->device_.get()->set_voice_volume = adev_set_voice_volume;
    adev_->device_.get()->set_master_volume = adev_set_master_volume;
    adev_->device_.get()->get_master_volume = adev_get_master_volume;
    adev_->device_.get()->set_master_mute = adev_set_master_mute;
    adev_->device_.get()->get_master_mute = adev_get_master_mute;
    adev_->device_.get()->set_mode = adev_set_mode;
    adev_->device_.get()->set_mic_mute = adev_set_mic_mute;
    adev_->device_.get()->get_mic_mute = adev_get_mic_mute;
    adev_->device_.get()->set_parameters = adev_set_parameters;
    adev_->device_.get()->get_parameters = adev_get_parameters;
    adev_->device_.get()->get_input_buffer_size = adev_get_input_buffer_size;
    adev_->device_.get()->open_output_stream = adev_open_output_stream;
    adev_->device_.get()->close_output_stream = adev_close_output_stream;
    adev_->device_.get()->open_input_stream = adev_open_input_stream;
    adev_->device_.get()->close_input_stream = adev_close_input_stream;
    adev_->device_.get()->create_audio_patch = adev_create_audio_patch;
    adev_->device_.get()->release_audio_patch = adev_release_audio_patch;
    adev_->device_.get()->get_audio_port_v7 = get_audio_port_v7;
    adev_->device_.get()->set_audio_port_config = adev_set_audio_port_config;
    adev_->device_.get()->dump = adev_dump;
    adev_->device_.get()->get_microphones = adev_get_microphones;
#ifdef USEHIDL7_1
    adev_->device_.get()->set_device_connected_state_v7 = adev_set_device_connected_state_v7;
#endif
    adev_->device_.get()->common.module = (struct hw_module_t *)module;
    *device = &(adev_->device_.get()->common);

    // visualizer lib
    if (access(VISUALIZER_LIBRARY_PATH, R_OK) == 0) {
        visualizer_lib_ = dlopen(VISUALIZER_LIBRARY_PATH, RTLD_NOW);
        if (visualizer_lib_ == NULL) {
            AHAL_ERR("DLOPEN failed for %s", VISUALIZER_LIBRARY_PATH);
        } else {
            AHAL_VERBOSE("DLOPEN successful for %s", VISUALIZER_LIBRARY_PATH);
            fnp_visualizer_start_output_ =
                        (int (*)(audio_io_handle_t, pal_stream_handle_t*))dlsym(visualizer_lib_,
                                                        "visualizer_hal_start_output");
            fnp_visualizer_stop_output_ =
                        (int (*)(audio_io_handle_t, pal_stream_handle_t*))dlsym(visualizer_lib_,
                                                        "visualizer_hal_stop_output");
        }
    }

    // offload effect lib
    if (access(OFFLOAD_EFFECTS_BUNDLE_LIBRARY_PATH, R_OK) == 0) {
        offload_effects_lib_ = dlopen(OFFLOAD_EFFECTS_BUNDLE_LIBRARY_PATH,
                                      RTLD_NOW);
        if (offload_effects_lib_ == NULL) {
            AHAL_ERR("DLOPEN failed for %s",
                  OFFLOAD_EFFECTS_BUNDLE_LIBRARY_PATH);
        } else {
            AHAL_VERBOSE("DLOPEN successful for %s",
                  OFFLOAD_EFFECTS_BUNDLE_LIBRARY_PATH);
            fnp_offload_effect_start_output_ =
                (int (*)(audio_io_handle_t, pal_stream_handle_t*))dlsym(
                                    offload_effects_lib_,
                                    "offload_effects_bundle_hal_start_output");
            fnp_offload_effect_stop_output_ =
                (int (*)(audio_io_handle_t, pal_stream_handle_t*))dlsym(
                                    offload_effects_lib_,
                                    "offload_effects_bundle_hal_stop_output");
        }
    }
    audio_extn_sound_trigger_init(adev_);
    AudioExtn::hfp_feature_init(property_get_bool("vendor.audio.feature.hfp.enable", false));
    AudioExtn::a2dp_source_feature_init(property_get_bool("vendor.audio.feature.a2dp_offload.enable", false));

    AudioExtn::audio_extn_fm_init();
    AudioExtn::audio_extn_kpi_optimize_feature_init(
            property_get_bool("vendor.audio.feature.kpi_optimize.enable", false));
    AudioExtn::battery_listener_feature_init(
            property_get_bool("vendor.audio.feature.battery_listener.enable", false));
    AudioExtn::battery_properties_listener_init(adev_on_battery_status_changed);
    is_charging = AudioExtn::battery_properties_is_charging();
    SetChargingMode(is_charging);
    AudioExtn::audio_extn_perf_lock_init();
    adev_->perf_lock_opts[0] = 0x40400000;
    adev_->perf_lock_opts[1] = 0x1;
    adev_->perf_lock_opts[2] = 0x40C00000;
    adev_->perf_lock_opts[3] = 0x1;
    adev_->perf_lock_opts_size = 4;

    voice_ = VoiceInit();
    mute_ = false;
    current_rotation = PAL_SPEAKER_ROTATION_LR;

    FillAndroidDeviceMap();
    audio_extn_gef_init(adev_);
    adev_init_ref_count += 1;

    memset(&microphones, 0, sizeof(microphone_characteristics_t));
    memset(&microphone_maps, 0, sizeof(PAL_MAX_INPUT_DEVICES*sizeof(snd_device_to_mic_map_t)));
    if (!parse_xml())
        mic_characteristics_available = true;

    return ret;
}

std::shared_ptr<AudioVoice> AudioDevice::VoiceInit() {
    std::shared_ptr<AudioVoice> voice (new AudioVoice());

    return voice;

}

int AudioDevice::SetGEFParam(void *data, int length) {
    return pal_set_param(PAL_PARAM_ID_UIEFFECT, data, length);
}


int AudioDevice::GetGEFParam(void *data, int *length) {
    return pal_get_param(PAL_PARAM_ID_UIEFFECT, nullptr, (size_t *)length, data);
}

std::shared_ptr<StreamOutPrimary> AudioDevice::OutGetStream(audio_io_handle_t handle) {
    std::shared_ptr<StreamOutPrimary> astream_out = NULL;
    out_list_mutex.lock();
    for (int i = 0; i < stream_out_list_.size(); i++) {
        if (stream_out_list_[i]->handle_ == handle) {
            AHAL_INFO("Found existing stream associated with iohandle %d",
                      handle);
            astream_out = stream_out_list_[i];
            break;
        }
    }

    out_list_mutex.unlock();
    return astream_out;
}

std::vector<std::shared_ptr<StreamOutPrimary>> AudioDevice::OutGetBLEStreamOutputs() {

   std::shared_ptr<StreamOutPrimary> astream_out;
   std::vector<std::shared_ptr<StreamOutPrimary>> astream_out_list;
   audio_stream_out* stream_out = NULL;

   /* In case of dev switch to BLE device, stream is associated with old
    * device but not the BLE until dev switch process completed. Thus get the all
    * active output streams.
    */
   out_list_mutex.lock();
   for (int i = 0; i < stream_out_list_.size(); i++) {
       stream_out_list_[i]->GetStreamHandle(&stream_out);
       if (stream_out_list_[i]->stream_.get() == (audio_stream_out*) stream_out) {
           astream_out_list.push_back(stream_out_list_[i]);
       }
   }
   out_list_mutex.unlock();
   return astream_out_list;
}

std::shared_ptr<StreamOutPrimary> AudioDevice::OutGetStream(audio_stream_t* stream_out) {

    std::shared_ptr<StreamOutPrimary> astream_out = NULL;
    AHAL_VERBOSE("stream_out(%p)", stream_out);
    out_list_mutex.lock();
    for (int i = 0; i < stream_out_list_.size(); i++) {
        if (stream_out_list_[i]->stream_.get() ==
                                        (audio_stream_out*) stream_out) {
            AHAL_VERBOSE("Found stream associated with stream_out");
            astream_out = stream_out_list_[i];
            AHAL_VERBOSE("astream_out(%p)", astream_out->stream_.get());
            break;
        }
    }
    out_list_mutex.unlock();
    return astream_out;
}

std::shared_ptr<StreamInPrimary> AudioDevice::InGetStream (audio_io_handle_t handle) {
    std::shared_ptr<StreamInPrimary> astream_in = NULL;
    in_list_mutex.lock();
    for (int i = 0; i < stream_in_list_.size(); i++) {
        if (stream_in_list_[i]->handle_ == handle) {
            AHAL_INFO("Found existing stream associated with iohandle %d",
                      handle);
            astream_in = stream_in_list_[i];
            break;
        }
    }
    in_list_mutex.unlock();
    return astream_in;
}

std::shared_ptr<StreamInPrimary> AudioDevice::InGetStream (audio_stream_t* stream_in) {
    std::shared_ptr<StreamInPrimary> astream_in = NULL;

    AHAL_VERBOSE("stream_in(%p)", stream_in);
    in_list_mutex.lock();
    for (int i = 0; i < stream_in_list_.size(); i++) {
        if (stream_in_list_[i]->stream_.get() == (audio_stream_in*) stream_in) {
            AHAL_VERBOSE("Found existing stream associated with astream_in");
            astream_in = stream_in_list_[i];
            AHAL_VERBOSE("astream_in(%p)", astream_in->stream_.get());
            break;
        }
    }
    in_list_mutex.unlock();
    return astream_in;
}

std::vector<std::shared_ptr<StreamInPrimary>> AudioDevice::InGetBLEStreamInputs() {

    std::shared_ptr<StreamInPrimary> astream_in;
    std::vector<std::shared_ptr<StreamInPrimary>> astream_in_list;
    audio_stream_in* stream_in = NULL;

   /* In case of dev switch to BLE device, stream is associated with old
    * device but not the BLE until dev switch process completed. Thus get the all
    * active input streams.
    */
    in_list_mutex.lock();
    for (int i = 0; i < stream_in_list_.size(); i++) {
        stream_in_list_[i]->GetStreamHandle(&stream_in);
        if (stream_in_list_[i]->stream_.get() == (audio_stream_in*)stream_in) {
            astream_in_list.push_back(stream_in_list_[i]);
        }
    }
    in_list_mutex.unlock();
    return astream_in_list;
}

int AudioDevice::SetMicMute(bool state) {
    int ret = 0;
    std::shared_ptr<StreamInPrimary> astream_in;
    mute_ = state;

    AHAL_DBG("%s: enter: %d", __func__, state);
    if (AudioExtn::audio_extn_hfp_is_active(adev_))
        ret = AudioExtn::audio_extn_hfp_set_mic_mute(state);
    if (voice_)
        ret = voice_->SetMicMute(state);
    for (int i = 0; i < stream_in_list_.size(); i++) {
         astream_in = stream_in_list_[i];
         if (astream_in) {
             AHAL_VERBOSE("Found existing stream associated with astream_in");
             ret = astream_in->SetMicMute(state);
         }
    }

    AHAL_DBG("exit: ret %d", ret);
    return ret;
}

int AudioDevice::GetMicMute(bool *state) {
    *state = mute_;

    return 0;
}

int AudioDevice::SetMode(const audio_mode_t mode) {
    int ret = 0;

    AHAL_DBG("enter: mode: %d", mode);
    ret = voice_->SetMode(mode);
    AHAL_DBG("Exit ret: %d", ret);
    return ret;
}

int AudioDevice::add_input_headset_if_usb_out_headset(int *device_count,
                              pal_device_id_t** pal_device_ids, bool conn_state)
{
    bool is_usb_headset = false;
    int count = *device_count;
    pal_device_id_t* temp = NULL;

    for (int i = 0; i < count; i++) {
         if (*pal_device_ids[i] == PAL_DEVICE_OUT_USB_HEADSET) {
             is_usb_headset = true;
             usb_out_headset = true;
             break;
         }
    }

    if (is_usb_headset) {
        temp = (pal_device_id_t *) realloc(*pal_device_ids,
            (count + 1) * sizeof(pal_device_id_t));
        if (!temp)
            return -ENOMEM;
        *pal_device_ids = temp;
        temp[count] = PAL_DEVICE_IN_USB_HEADSET;
        *device_count = count + 1;
        if (conn_state)
           usb_input_dev_enabled = true;
        else {
           usb_input_dev_enabled = false;
           usb_out_headset = false;
        }
    }
    return 0;
}

int AudioDevice::SetParameters(const char *kvpairs) {
    int ret = 0, val = 0;
    struct str_parms *parms = NULL;
    char value[256];
    int pal_device_count = 0;
    pal_device_id_t* pal_device_ids = NULL;
    char *test_r = NULL;
    char *cfg_str = NULL;
    bool changes_done = false;
    audio_stream_in* stream_in = NULL;
    audio_stream_out* stream_out = NULL;
    std::shared_ptr<StreamInPrimary> astream_in = NULL;
    std::shared_ptr<StreamOutPrimary> astream_out = NULL;
    uint8_t channels = 0;
    std::set<audio_devices_t> new_devices;

    AHAL_DBG("enter: %s", kvpairs);
    ret = voice_->VoiceSetParameters(kvpairs);
    if (ret)
        AHAL_ERR("Error in VoiceSetParameters %d", ret);

    parms = str_parms_create_str(kvpairs);
    if (!parms) {
        AHAL_ERR("Error in str_parms_create_str");
        ret = 0;
        return ret;
    }
    AudioExtn::audio_extn_set_parameters(adev_, parms);

    if ( (property_get_bool("vendor.audio.hdr.record.enable", false)) ||
         (property_get_bool("vendor.audio.hdr.spf.record.enable", false))) {
        changes_done = hdr_set_parameters(adev_, parms);
        if (changes_done) {
            for (int i = 0; i < stream_in_list_.size(); i++) {
                stream_in_list_[i]->GetStreamHandle(&stream_in);
                astream_in = adev_->InGetStream((audio_stream_t*)stream_in);
                if ( (astream_in->source_ == AUDIO_SOURCE_UNPROCESSED) &&
                   (astream_in->config_.sample_rate == 48000) ) {
                    AHAL_DBG("Forcing PAL device switch for HDR");
                    channels =
                        audio_channel_count_from_in_mask(astream_in->config_.channel_mask);
                    if (channels == 4) {
                        if (adev_->hdr_record_enabled) {
                            new_devices = astream_in->mAndroidInDevices;
                            astream_in->RouteStream(new_devices, true);
                        }
                    }
                    break;
                } else if (property_get_bool("vendor.audio.hdr.spf.record.enable", false)) {
                    new_devices = astream_in->mAndroidInDevices;
                    astream_in->RouteStream(new_devices, true);
                }
            }
        }
    }

    ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_HAC, value, sizeof(value));
    if (ret >= 0) {
        adev_->hac_voip = false;
        if (strcmp(value, AUDIO_PARAMETER_VALUE_HAC_ON) == 0) {
            adev_->hac_voip = true;
            for (int i = 0; i < stream_out_list_.size(); i++) {
                stream_out_list_[i]->GetStreamHandle(&stream_out);
                astream_out = adev_->OutGetStream((audio_stream_t*)stream_out);
                if (astream_out->GetUseCase() == USECASE_AUDIO_PLAYBACK_VOIP) {
                    new_devices = astream_out->mAndroidOutDevices;
                    astream_out->RouteStream(new_devices, true);
                    break;
                }
            }
        }
    }

    ret = str_parms_get_str(parms, "screen_state", value, sizeof(value));
    if (ret >= 0) {
        pal_param_screen_state_t param_screen_st;
        if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0) {
            param_screen_st.screen_state = true;
            AHAL_DBG(" - screen = on");
            ret = pal_set_param( PAL_PARAM_ID_SCREEN_STATE, (void*)&param_screen_st, sizeof(pal_param_screen_state_t));
        } else {
            AHAL_DBG(" - screen = off");
            param_screen_st.screen_state = false;
            ret = pal_set_param( PAL_PARAM_ID_SCREEN_STATE, (void*)&param_screen_st, sizeof(pal_param_screen_state_t));
        }
    }

    ret = str_parms_get_str(parms, "UHQA", value, sizeof(value));
    if (ret >= 0) {
        pal_param_uhqa_t param_uhqa_flag;
        if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0) {
            param_uhqa_flag.uhqa_state = true;
            AHAL_DBG(" - UHQA = on");
            ret = pal_set_param(PAL_PARAM_ID_UHQA_FLAG, (void*)&param_uhqa_flag,
                          sizeof(pal_param_uhqa_t));
        } else {
            param_uhqa_flag.uhqa_state = false;
            AHAL_DBG(" - UHQA = false");
            ret = pal_set_param(PAL_PARAM_ID_UHQA_FLAG, (void*)&param_uhqa_flag,
                          sizeof(pal_param_uhqa_t));
        }
    }

    ret = str_parms_get_str(parms, AUDIO_PARAMETER_DEVICE_CONNECT,
                            value, sizeof(value));
    if (ret >= 0) {
        pal_param_device_connection_t param_device_connection;
        val = atoi(value);
        audio_devices_t device = (audio_devices_t)val;

        if (audio_is_usb_out_device(device) || audio_is_usb_in_device(device)) {
            ret = str_parms_get_str(parms, "card", value, sizeof(value));
            if (ret >= 0) {
                param_device_connection.device_config.usb_addr.card_id = atoi(value);
                if ((usb_card_id_ == param_device_connection.device_config.usb_addr.card_id) &&
                    (audio_is_usb_in_device(device)) && (usb_input_dev_enabled == true)) {
                    AHAL_INFO("plugin card :%d device num=%d already added", usb_card_id_,
                          param_device_connection.device_config.usb_addr.device_num);
                    ret = 0;
                    goto exit;
                }

                usb_card_id_ = param_device_connection.device_config.usb_addr.card_id;
                AHAL_INFO("plugin card=%d",
                    param_device_connection.device_config.usb_addr.card_id);
            }
            ret = str_parms_get_str(parms, "device", value, sizeof(value));
            if (ret >= 0) {
                param_device_connection.device_config.usb_addr.device_num = atoi(value);
                usb_dev_num_ = param_device_connection.device_config.usb_addr.device_num;
                AHAL_INFO("plugin device num=%d",
                    param_device_connection.device_config.usb_addr.device_num);
            }
        } else if (val == AUDIO_DEVICE_OUT_AUX_DIGITAL) {
            int controller = -1, stream = -1;
            AudioExtn::get_controller_stream_from_params(parms, &controller, &stream);
            param_device_connection.device_config.dp_config.controller = controller;
            dp_controller = controller;
            param_device_connection.device_config.dp_config.stream = stream;
            dp_stream = stream;
            AHAL_INFO("plugin device cont %d stream %d", controller, stream);
        }

        if (device) {
            pal_device_ids = (pal_device_id_t *) calloc(1, sizeof(pal_device_id_t));
            pal_device_count = GetPalDeviceIds({device}, pal_device_ids);
            ret = add_input_headset_if_usb_out_headset(&pal_device_count, &pal_device_ids, true);
            if (ret) {
                if (pal_device_ids)
                    free(pal_device_ids);
                AHAL_ERR("adding input headset failed, error:%d", ret);
                goto exit;
            }
            for (int i = 0; i < pal_device_count; i++) {
                param_device_connection.connection_state = true;
                param_device_connection.id = pal_device_ids[i];
                ret = pal_set_param(PAL_PARAM_ID_DEVICE_CONNECTION,
                        (void*)&param_device_connection,
                        sizeof(pal_param_device_connection_t));
                if (ret!=0) {
                    AHAL_ERR("pal set param failed for device connection, pal_device_ids:%d",
                             pal_device_ids[i]);
                }
            }
            AHAL_INFO("pal set param success  for device connection");
            /* check if capture profile is supported or not */
           if (audio_is_usb_out_device(device) || audio_is_usb_in_device(device)) {
                pal_param_device_capability_t *device_cap_query = (pal_param_device_capability_t *)
                                                          malloc(sizeof(pal_param_device_capability_t));
                if (device_cap_query) {
                    dynamic_media_config_t dynamic_media_config;
                    size_t payload_size = 0;
                    device_cap_query->id = PAL_DEVICE_IN_USB_HEADSET;
                    device_cap_query->addr.card_id = usb_card_id_;
                    device_cap_query->addr.device_num = usb_dev_num_;
                    device_cap_query->config = &dynamic_media_config;
                    device_cap_query->is_playback = false;
                    ret = pal_get_param(PAL_PARAM_ID_DEVICE_CAPABILITY,
                            (void **)&device_cap_query,
                            &payload_size, nullptr);
                    if ((dynamic_media_config.sample_rate[0] == 0 && dynamic_media_config.format[0] == 0 &&
                            dynamic_media_config.mask[0] == 0) || (dynamic_media_config.jack_status == false))
                        usb_input_dev_enabled = false;
                    else
                        usb_input_dev_enabled = true;
                    free(device_cap_query);
                } else {
                    AHAL_ERR("Failed to allocate mem for device_cap_query");
                }
            }

            if (pal_device_ids) {
                free(pal_device_ids);
                pal_device_ids = NULL;
            }
        }
    }

    /* Checking for Device rotation */
    ret = str_parms_get_int(parms, "rotation", &val);
    if (ret >= 0) {
        int isRotationReq = 0;
        pal_param_device_rotation_t param_device_rotation;

        switch (val) {
        case 270:
        {
            if (PAL_SPEAKER_ROTATION_LR == current_rotation) {
                /* Device rotated from normal position to inverted landscape. */
                current_rotation = PAL_SPEAKER_ROTATION_RL;
                isRotationReq = 1;
                param_device_rotation.rotation_type = PAL_SPEAKER_ROTATION_RL;
            }
        }
        break;
        case 0:
        case 180:
        case 90:
        {
            if (PAL_SPEAKER_ROTATION_RL == current_rotation) {
                /* Phone was in inverted landspace and now is changed to portrait
                 * or inverted portrait. Notify PAL to swap the speaker.
                 */
                current_rotation = PAL_SPEAKER_ROTATION_LR;
                isRotationReq = 1;
                param_device_rotation.rotation_type = PAL_SPEAKER_ROTATION_LR;
            }
        }
        break;
        default:
            AHAL_ERR("error unexpected rotation of %d", val);
            isRotationReq = -EINVAL;
        }
        if (1 == isRotationReq) {
            /* Swap the speakers */
            AHAL_DBG("Swapping the speakers ");
            ret = pal_set_param(PAL_PARAM_ID_DEVICE_ROTATION,
                    (void*)&param_device_rotation,
                    sizeof(pal_param_device_rotation_t));
            AHAL_DBG("Speakers swapped ");
        }
    }

    /* Speaker Protection: Factory Test Mode */
    ret = str_parms_get_str(parms, "fbsp_cfg_wait_time", value, sizeof(value));
    if (ret >= 0) {
        str_parms_del(parms, "fbsp_cfg_wait_time");
        cfg_str = strtok_r(value, ";", &test_r);
        if (cfg_str != NULL) {
            pal_spkr_prot_payload spPayload;
            spPayload.operationMode = PAL_SP_MODE_FACTORY_TEST;
            spPayload.spkrHeatupTime = atoi(cfg_str);

            ret = str_parms_get_str(parms, "fbsp_cfg_ftm_time", value, sizeof(value));
            if (ret >= 0) {
                str_parms_del(parms, "fbsp_cfg_ftm_time");
                cfg_str = strtok_r(value, ";", &test_r);
                if (cfg_str != NULL) {
                    spPayload.operationModeRunTime = atoi(cfg_str);
                    ret = pal_set_param(PAL_PARAM_ID_SP_MODE, (void*)&spPayload,
                                sizeof(pal_spkr_prot_payload));
                } else {
                    AHAL_ERR("Unable to parse the FTM time");
                }
            } else {
                AHAL_ERR("Parameter missing for the FTM time");
            }
        } else {
            AHAL_ERR("Unable to parse the FTM wait time");
        }
    }

    /* Speaker Protection: V-validation mode */
    ret = str_parms_get_str(parms, "fbsp_v_vali_wait_time", value, sizeof(value));
    if (ret >= 0) {
        str_parms_del(parms, "fbsp_v_vali_wait_time");
        cfg_str = strtok_r(value, ";", &test_r);
        if (cfg_str != NULL) {
            pal_spkr_prot_payload spPayload;
            spPayload.operationMode = PAL_SP_MODE_V_VALIDATION;
            spPayload.spkrHeatupTime = atoi(cfg_str);

            ret = str_parms_get_str(parms, "fbsp_v_vali_vali_time", value, sizeof(value));
            if (ret >= 0) {
                str_parms_del(parms, "fbsp_v_vali_vali_time");
                cfg_str = strtok_r(value, ";", &test_r);
                if (cfg_str != NULL) {
                    spPayload.operationModeRunTime = atoi(cfg_str);
                    ret = pal_set_param(PAL_PARAM_ID_SP_MODE, (void*)&spPayload,
                                sizeof(pal_spkr_prot_payload));
                } else {
                    AHAL_ERR("Unable to parse the V_Validation time");
                }
            } else {
                AHAL_ERR("Parameter missing for the V-Validation time");
            }
        } else {
            AHAL_ERR("Unable to parse the V-Validation wait time");
        }
    }

    /* Speaker Protection: Dynamic calibration mode */
    ret = str_parms_get_str(parms, "trigger_spkr_cal", value, sizeof(value));
    if (ret >= 0) {
        if ((strcmp(value, "true") == 0) || (strcmp(value, "yes") == 0)) {
            pal_spkr_prot_payload spPayload;
            spPayload.operationMode = PAL_SP_MODE_DYNAMIC_CAL;
            ret = pal_set_param(PAL_PARAM_ID_SP_MODE, (void*)&spPayload,
                        sizeof(pal_spkr_prot_payload));
        }
    }

    ret = str_parms_get_str(parms, AUDIO_PARAMETER_DEVICE_DISCONNECT,
                            value, sizeof(value));
    if (ret >= 0) {
        pal_param_device_connection_t param_device_connection;
        val = atoi(value);
        audio_devices_t device = (audio_devices_t)val;
        if (audio_is_usb_out_device(device) || audio_is_usb_in_device(device)) {
            ret = str_parms_get_str(parms, "card", value, sizeof(value));
            if (ret >= 0)
                param_device_connection.device_config.usb_addr.card_id = atoi(value);
            ret = str_parms_get_str(parms, "device", value, sizeof(value));
            if (ret >= 0)
                param_device_connection.device_config.usb_addr.device_num = atoi(value);
            if ((usb_card_id_ == param_device_connection.device_config.usb_addr.card_id) &&
                (audio_is_usb_in_device(device)) && (usb_input_dev_enabled == true)) {
                   usb_input_dev_enabled = false;
                   usb_out_headset = false;
                   AHAL_DBG("usb_input_dev_enabled flag is cleared.");
            }
        } else if (val == AUDIO_DEVICE_OUT_AUX_DIGITAL) {
            int controller = -1, stream = -1;
            AudioExtn::get_controller_stream_from_params(parms, &controller, &stream);
            param_device_connection.device_config.dp_config.controller = controller;
            param_device_connection.device_config.dp_config.stream = stream;
            dp_stream = stream;
            AHAL_INFO("plugin device cont %d stream %d", controller, stream);
        }

        if (device) {
            pal_device_ids = (pal_device_id_t *) calloc(1, sizeof(pal_device_id_t));
            pal_device_count = GetPalDeviceIds({device}, pal_device_ids);
            ret = add_input_headset_if_usb_out_headset(&pal_device_count, &pal_device_ids, false);
            if (ret) {
                if (pal_device_ids)
                    free(pal_device_ids);
                AHAL_ERR("adding input headset failed, error:%d", ret);
                goto exit;
            }
            for (int i = 0; i < pal_device_count; i++) {
                param_device_connection.connection_state = false;
                param_device_connection.id = pal_device_ids[i];
                ret = pal_set_param(PAL_PARAM_ID_DEVICE_CONNECTION,
                        (void*)&param_device_connection,
                        sizeof(pal_param_device_connection_t));
                if (ret!=0) {
                    AHAL_ERR("pal set param failed for device disconnect");
                }
                AHAL_INFO("pal set param sucess for device disconnect");
            }
        }
    }

    if (pal_device_ids) {
        free(pal_device_ids);
        pal_device_ids = NULL;
    }

    /* A2DP parameters */
    ret = str_parms_get_str(parms, AUDIO_PARAMETER_RECONFIG_A2DP, value, sizeof(value));
    if (ret >= 0) {
        pal_param_bta2dp_t param_bt_a2dp;
        param_bt_a2dp.reconfig = true;

        AHAL_INFO("BT A2DP Reconfig command received");
        ret = pal_set_param(PAL_PARAM_ID_BT_A2DP_RECONFIG, (void *)&param_bt_a2dp,
                            sizeof(pal_param_bta2dp_t));
    }

    ret = str_parms_get_str(parms, "A2dpSuspended" , value, sizeof(value));
    if (ret >= 0) {
        pal_param_bta2dp_t param_bt_a2dp;

        if (strncmp(value, "true", 4) == 0)
            param_bt_a2dp.a2dp_suspended = true;
        else
            param_bt_a2dp.a2dp_suspended = false;

        param_bt_a2dp.dev_id = PAL_DEVICE_OUT_BLUETOOTH_A2DP;

        AHAL_INFO("BT A2DP Suspended = %s, command received", value);
        ret = pal_set_param(PAL_PARAM_ID_BT_A2DP_SUSPENDED, (void *)&param_bt_a2dp,
                            sizeof(pal_param_bta2dp_t));
    }

    ret = str_parms_get_str(parms, "TwsChannelConfig", value, sizeof(value));
    if (ret >= 0) {
        pal_param_bta2dp_t param_bt_a2dp;

        AHAL_INFO("Setting tws channel mode to %s", value);
        if (!(strncmp(value, "mono", strlen(value))))
            param_bt_a2dp.is_tws_mono_mode_on = true;
        else if (!(strncmp(value,"dual-mono",strlen(value))))
            param_bt_a2dp.is_tws_mono_mode_on = false;
        ret = pal_set_param(PAL_PARAM_ID_BT_A2DP_TWS_CONFIG, (void *)&param_bt_a2dp,
                            sizeof(pal_param_bta2dp_t));
    }

    ret = str_parms_get_str(parms, "LEAMono", value, sizeof(value));
    if (ret >= 0) {
        pal_param_bta2dp_t param_bt_a2dp;

        AHAL_INFO("Setting LC3 channel mode to %s", value);
        if (!(strncmp(value, "true", strlen(value))))
            param_bt_a2dp.is_lc3_mono_mode_on = true;
        else
            param_bt_a2dp.is_lc3_mono_mode_on = false;
        ret = pal_set_param(PAL_PARAM_ID_BT_A2DP_LC3_CONFIG, (void *)&param_bt_a2dp,
                            sizeof(pal_param_bta2dp_t));
    }

    /* SCO parameters */
    ret = str_parms_get_str(parms, "BT_SCO", value, sizeof(value));
    if (ret >= 0) {
        pal_param_btsco_t param_bt_sco;
        memset(&param_bt_sco, 0, sizeof(pal_param_btsco_t));
        if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0) {
            param_bt_sco.bt_sco_on = true;
        } else {
            param_bt_sco.bt_sco_on = false;
        }

        AHAL_INFO("BTSCO on = %d", param_bt_sco.bt_sco_on);
        ret = pal_set_param(PAL_PARAM_ID_BT_SCO, (void *)&param_bt_sco,
                            sizeof(pal_param_btsco_t));
    }

    ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_BT_SCO_WB, value, sizeof(value));
    if (ret >= 0) {
        pal_param_btsco_t param_bt_sco = {};
        if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0)
            param_bt_sco.bt_wb_speech_enabled = true;
        else
            param_bt_sco.bt_wb_speech_enabled = false;

        AHAL_INFO("BTSCO WB mode = %d", param_bt_sco.bt_wb_speech_enabled);
        ret = pal_set_param(PAL_PARAM_ID_BT_SCO_WB, (void *)&param_bt_sco,
                            sizeof(pal_param_btsco_t));
    }

    ret = str_parms_get_str(parms, "bt_swb", value, sizeof(value));
    if (ret >= 0) {
        pal_param_btsco_t param_bt_sco = {};
        val = atoi(value);
        param_bt_sco.bt_swb_speech_mode = val;
        AHAL_INFO("BTSCO SWB mode = 0x%x", val);
        ret = pal_set_param(PAL_PARAM_ID_BT_SCO_SWB, (void *)&param_bt_sco,
                            sizeof(pal_param_btsco_t));
    }

    ret = str_parms_get_str(parms, "bt_ble", value, sizeof(value));
    if (ret >= 0) {
        pal_param_btsco_t param_bt_sco = {};
        if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0) {
            bt_lc3_speech_enabled = true;

            // turn off wideband, super-wideband
            param_bt_sco.bt_wb_speech_enabled = false;
            ret = pal_set_param(PAL_PARAM_ID_BT_SCO_WB, (void *)&param_bt_sco,
                                sizeof(pal_param_btsco_t));

            param_bt_sco.bt_swb_speech_mode = 0xFFFF;
            ret = pal_set_param(PAL_PARAM_ID_BT_SCO_SWB, (void *)&param_bt_sco,
                                sizeof(pal_param_btsco_t));
        } else {
            bt_lc3_speech_enabled = false;
            param_bt_sco.bt_lc3_speech_enabled = false;
            ret = pal_set_param(PAL_PARAM_ID_BT_SCO_LC3, (void *)&param_bt_sco,
                                sizeof(pal_param_btsco_t));

            // clear btsco_lc3_cfg to avoid stale and partial cfg being used in next round
            memset(&btsco_lc3_cfg, 0, sizeof(btsco_lc3_cfg_t));
        }
        AHAL_INFO("BTSCO LC3 mode = %d", bt_lc3_speech_enabled);
    }

    ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_BT_NREC, value, sizeof(value));
    if (ret >= 0) {
        pal_param_btsco_t param_bt_sco = {};
        if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0) {
            AHAL_INFO("BTSCO NREC mode = ON");
            param_bt_sco.bt_sco_nrec = true;
        } else {
            AHAL_INFO("BTSCO NREC mode = OFF");
            param_bt_sco.bt_sco_nrec = false;
        }
        ret = pal_set_param(PAL_PARAM_ID_BT_SCO_NREC, (void *)&param_bt_sco,
                            sizeof(pal_param_btsco_t));
    }

    for (auto& key : lc3_reserved_params) {
        ret = str_parms_get_str(parms, key, value, sizeof(value));
        if (ret < 0)
            continue;

        if (!strcmp(key, "Codec") && (!strcmp(value, "LC3"))) {
            btsco_lc3_cfg.fields_map |= LC3_CODEC_BIT;
        } else if (!strcmp(key, "StreamMap")) {
            strlcpy(btsco_lc3_cfg.streamMap, value, PAL_LC3_MAX_STRING_LEN);
            btsco_lc3_cfg.fields_map |= LC3_STREAM_MAP_BIT;
        } else if (!strcmp(key, "FrameDuration")) {
            btsco_lc3_cfg.frame_duration = atoi(value);
            btsco_lc3_cfg.fields_map |= LC3_FRAME_DURATION_BIT;
        } else if (!strcmp(key, "Blocks_forSDU")) {
            btsco_lc3_cfg.num_blocks = atoi(value);
            btsco_lc3_cfg.fields_map |= LC3_BLOCKS_FORSDU_BIT;
        } else if (!strcmp(key, "rxconfig_index")) {
            btsco_lc3_cfg.rxconfig_index = atoi(value);
            btsco_lc3_cfg.fields_map |= LC3_RXCFG_IDX_BIT;
        } else if (!strcmp(key, "txconfig_index")) {
            btsco_lc3_cfg.txconfig_index = atoi(value);
            btsco_lc3_cfg.fields_map |= LC3_TXCFG_IDX_BIT;
        } else if (!strcmp(key, "version")) {
            btsco_lc3_cfg.api_version = atoi(value);
            btsco_lc3_cfg.fields_map |= LC3_VERSION_BIT;
        } else if (!strcmp(key, "vendor")) {
            strlcpy(btsco_lc3_cfg.vendor, value, PAL_LC3_MAX_STRING_LEN);
            btsco_lc3_cfg.fields_map |= LC3_VENDOR_BIT;
        }
    }

    if (((btsco_lc3_cfg.fields_map & LC3_BIT_MASK) == LC3_BIT_VALID) &&
           (bt_lc3_speech_enabled == true)) {
        pal_param_btsco_t param_bt_sco = {};
        param_bt_sco.bt_lc3_speech_enabled  = bt_lc3_speech_enabled;
        param_bt_sco.lc3_cfg.frame_duration = btsco_lc3_cfg.frame_duration;
        param_bt_sco.lc3_cfg.num_blocks     = btsco_lc3_cfg.num_blocks;
        param_bt_sco.lc3_cfg.rxconfig_index = btsco_lc3_cfg.rxconfig_index;
        param_bt_sco.lc3_cfg.txconfig_index = btsco_lc3_cfg.txconfig_index;
        param_bt_sco.lc3_cfg.api_version    = btsco_lc3_cfg.api_version;
        strlcpy(param_bt_sco.lc3_cfg.streamMap, btsco_lc3_cfg.streamMap, PAL_LC3_MAX_STRING_LEN);
        strlcpy(param_bt_sco.lc3_cfg.vendor, btsco_lc3_cfg.vendor, PAL_LC3_MAX_STRING_LEN);

        AHAL_INFO("BTSCO LC3 mode = on, sending..");
        ret = pal_set_param(PAL_PARAM_ID_BT_SCO_LC3, (void *)&param_bt_sco,
                            sizeof(pal_param_btsco_t));

        memset(&btsco_lc3_cfg, 0, sizeof(btsco_lc3_cfg_t));
    }

    ret = str_parms_get_str(parms, "wfd_channel_cap", value, sizeof(value));
    if (ret >= 0) {
        pal_param_proxy_channel_config_t param_out_proxy;

        val = atoi(value);
        param_out_proxy.num_proxy_channels = val;
        AHAL_INFO("Proxy channels: %d", val);
        ret = pal_set_param(PAL_PARAM_ID_PROXY_CHANNEL_CONFIG, (void *)&param_out_proxy,
                sizeof(pal_param_proxy_channel_config_t));
    }

    ret = str_parms_get_str(parms, "haptics_volume", value, sizeof(value));
    if (ret >= 0) {
        struct pal_volume_data* volume = NULL;
        volume = (struct pal_volume_data *)malloc(sizeof(struct pal_volume_data)
                      +sizeof(struct pal_channel_vol_kv));
        if (volume) {
            volume->no_of_volpair = 1;
            //For haptics, there is only one channel (FL).
            volume->volume_pair[0].channel_mask = 0x01;
            volume->volume_pair[0].vol = atof(value);
            AHAL_INFO("Setting Haptics Volume as %f", volume->volume_pair[0].vol);
            ret = pal_set_param(PAL_PARAM_ID_HAPTICS_VOLUME, (void *)volume,
                     sizeof(pal_volume_data));
            free(volume);
        }
    }

    ret = str_parms_get_str(parms, "haptics_intensity", value, sizeof(value));
    if (ret >=0) {
        pal_param_haptics_intensity_t hIntensity;
        val = atoi(value);
        hIntensity.intensity = val;
        AHAL_INFO("Setting Haptics Volume as %d", hIntensity.intensity);
        ret = pal_set_param(PAL_PARAM_ID_HAPTICS_INTENSITY, (void *)&hIntensity,
                 sizeof(pal_param_haptics_intensity_t));
    }

    ret = str_parms_get_str(parms, "A2dpCaptureSuspend", value, sizeof(value));
    if (ret >= 0) {
        pal_param_bta2dp_t param_bt_a2dp;

        if (strncmp(value, "true", 4) == 0)
            param_bt_a2dp.a2dp_capture_suspended = true;
        else
            param_bt_a2dp.a2dp_capture_suspended = false;

        param_bt_a2dp.dev_id = PAL_DEVICE_IN_BLUETOOTH_A2DP;

        AHAL_INFO("BT A2DP Capture Suspended = %s, command received", value);
        ret = pal_set_param(PAL_PARAM_ID_BT_A2DP_CAPTURE_SUSPENDED, (void*)&param_bt_a2dp,
            sizeof(pal_param_bta2dp_t));
    }


exit:
    if (parms)
        str_parms_destroy(parms);

    AHAL_DBG("exit: %s", kvpairs);
    return 0;
}


int AudioDevice::SetVoiceVolume(float volume) {
    return voice_->SetVoiceVolume(volume);
}

char* AudioDevice::GetParameters(const char *keys) {
    int32_t ret;
    int32_t val = 0;
    char *str;
    char value[256]={0};
    size_t size = 0;
    struct str_parms *reply = str_parms_create();
    struct str_parms *query = str_parms_create_str(keys);

    if (!query || !reply) {
        if (reply) {
            str_parms_destroy(reply);
        }
        if (query) {
            str_parms_destroy(query);
        }
        AHAL_ERR("failed to create query or reply");
        return NULL;
    }

    AHAL_VERBOSE("enter");

    ret = str_parms_get_str(query, AUDIO_PARAMETER_A2DP_RECONFIG_SUPPORTED,
                            value, sizeof(value));
    if (ret >= 0) {
        pal_param_bta2dp_t *param_bt_a2dp_ptr, param_bt_a2dp;
        param_bt_a2dp_ptr = &param_bt_a2dp;

        param_bt_a2dp_ptr->dev_id = PAL_DEVICE_OUT_BLUETOOTH_A2DP;
        ret = pal_get_param(PAL_PARAM_ID_BT_A2DP_RECONFIG_SUPPORTED,
                            (void **)&param_bt_a2dp_ptr, &size, nullptr);
        if (!ret) {
            if (size < sizeof(pal_param_bta2dp_t)) {
                AHAL_ERR("size returned is smaller for BT_A2DP_RECONFIG_SUPPORTED");
                goto exit;
            }
            val = param_bt_a2dp_ptr->reconfig_supported;
            str_parms_add_int(reply, AUDIO_PARAMETER_A2DP_RECONFIG_SUPPORTED, val);
            AHAL_VERBOSE("isReconfigA2dpSupported = %d", val);
        }
    }

    ret = str_parms_get_str(query, "A2dpSuspended", value, sizeof(value));
    if (ret >= 0) {
        pal_param_bta2dp_t *param_bt_a2dp_ptr, param_bt_a2dp;
        param_bt_a2dp_ptr = &param_bt_a2dp;

        param_bt_a2dp_ptr->dev_id = PAL_DEVICE_OUT_BLUETOOTH_A2DP;
        ret = pal_get_param(PAL_PARAM_ID_BT_A2DP_SUSPENDED,
                      (void **)&param_bt_a2dp_ptr, &size, nullptr);
        if (!ret) {
            if (size < sizeof(pal_param_bta2dp_t)) {
                AHAL_ERR("size returned is smaller for BT_A2DP_SUSPENDED");
                goto exit;
            }
            val = param_bt_a2dp_ptr->a2dp_suspended;
            str_parms_add_int(reply, "A2dpSuspended", val);
            AHAL_VERBOSE("A2dpSuspended = %d", val);
        }
    }

    ret = str_parms_get_str(query, "get_ftm_param", value, sizeof(value));

    if (ret >= 0) {
        char ftm_value[255];
        ret = pal_get_param(PAL_PARAM_ID_SP_MODE, (void **)&ftm_value, &size, nullptr);
        if (!ret) {
            if (size > 0) {
                str_parms_add_str(reply, "get_ftm_param", ftm_value);
            }
            else
                AHAL_ERR("Error happened for getting FTM param");
        }

    }

    ret = str_parms_get_str(query, "get_spkr_cal", value, sizeof(value));
    if (ret >= 0) {
        char cal_value[255];
        ret = pal_get_param(PAL_PARAM_ID_SP_GET_CAL, (void **)&cal_value, &size, nullptr);
        if (!ret) {
            if (size > 0) {
                str_parms_add_str(reply, "get_spkr_cal", cal_value);
            }
            else
                AHAL_ERR("Error happened for getting Cal param");
        }
    }

    AudioExtn::audio_extn_get_parameters(adev_, query, reply);
    if (voice_)
        voice_->VoiceGetParameters(query, reply);

    if (property_get_bool("vendor.audio.hdr.record.enable", false))
        hdr_get_parameters(adev_, query, reply);

exit:
    str = str_parms_to_str(reply);
    str_parms_destroy(query);
    str_parms_destroy(reply);

    if (str)
        AHAL_VERBOSE("exit: returns - %s", str);

    return str;
}

void AudioDevice::FillAndroidDeviceMap() {
    android_device_map_.clear();
    /* go through all devices and pushback */

    android_device_map_.insert(std::make_pair(AUDIO_DEVICE_NONE, PAL_DEVICE_NONE));
    android_device_map_.insert(std::make_pair(AUDIO_DEVICE_OUT_EARPIECE, PAL_DEVICE_OUT_HANDSET));
    android_device_map_.insert(std::make_pair(AUDIO_DEVICE_OUT_SPEAKER, PAL_DEVICE_OUT_SPEAKER));
    android_device_map_.insert(std::make_pair(AUDIO_DEVICE_OUT_WIRED_HEADSET, PAL_DEVICE_OUT_WIRED_HEADSET));
    android_device_map_.insert(std::make_pair(AUDIO_DEVICE_OUT_WIRED_HEADPHONE, PAL_DEVICE_OUT_WIRED_HEADPHONE));
    android_device_map_.insert(std::make_pair(AUDIO_DEVICE_OUT_BLUETOOTH_SCO, PAL_DEVICE_OUT_BLUETOOTH_SCO));
    android_device_map_.insert(std::make_pair(AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET, PAL_DEVICE_OUT_BLUETOOTH_SCO));
    android_device_map_.insert(std::make_pair(AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT, PAL_DEVICE_OUT_BLUETOOTH_SCO));
    android_device_map_.insert(std::make_pair(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP, PAL_DEVICE_OUT_BLUETOOTH_A2DP));
    android_device_map_.insert(std::make_pair(AUDIO_DEVICE_OUT_BLE_HEADSET, PAL_DEVICE_OUT_BLUETOOTH_BLE));
    android_device_map_.insert(std::make_pair(AUDIO_DEVICE_OUT_BLE_SPEAKER, PAL_DEVICE_OUT_BLUETOOTH_BLE));
    //android_device_map_.insert(std::make_pair(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES, PAL_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES));
    //android_device_map_.insert(std::make_pair(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER, PAL_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER));
    android_device_map_.insert(std::make_pair(AUDIO_DEVICE_OUT_AUX_DIGITAL, PAL_DEVICE_OUT_AUX_DIGITAL));
    android_device_map_.insert(std::make_pair(AUDIO_DEVICE_OUT_HDMI, PAL_DEVICE_OUT_HDMI));
    //android_device_map_.insert(std::make_pair(AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET, PAL_DEVICE_OUT_ANLG_DOCK_HEADSET));
    //android_device_map_.insert(std::make_pair(AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET, PAL_DEVICE_OUT_DGTL_DOCK_HEADSET));
    //android_device_map_.insert(std::make_pair(AUDIO_DEVICE_OUT_USB_ACCESSORY, PAL_DEVICE_OUT_USB_ACCESSORY));
    android_device_map_.insert(std::make_pair(AUDIO_DEVICE_OUT_USB_DEVICE, PAL_DEVICE_OUT_USB_DEVICE));
    //android_device_map_.insert(std::make_pair(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, PAL_DEVICE_OUT_REMOTE_SUBMIX));
    android_device_map_.insert(std::make_pair(AUDIO_DEVICE_OUT_TELEPHONY_TX, PAL_DEVICE_NONE));
    android_device_map_.insert(std::make_pair(AUDIO_DEVICE_OUT_LINE, PAL_DEVICE_OUT_WIRED_HEADPHONE));
    //android_device_map_.insert(std::make_pair(AUDIO_DEVICE_OUT_HDMI_ARC, PAL_DEVICE_OUT_HDMI_ARC));
    android_device_map_.insert(std::make_pair(AUDIO_DEVICE_OUT_SPDIF, PAL_DEVICE_OUT_SPDIF));
    android_device_map_.insert(std::make_pair(AUDIO_DEVICE_OUT_FM, PAL_DEVICE_OUT_FM));
    android_device_map_.insert(std::make_pair(AUDIO_DEVICE_OUT_AUX_LINE, PAL_DEVICE_OUT_AUX_LINE));
    android_device_map_.insert(std::make_pair(AUDIO_DEVICE_OUT_SPEAKER_SAFE, PAL_DEVICE_OUT_SPEAKER));
    //android_device_map_.insert(std::make_pair(AUDIO_DEVICE_OUT_IP, PAL_DEVICE_OUT_IP));
    //android_device_map_.insert(std::make_pair(AUDIO_DEVICE_OUT_BUS, PAL_DEVICE_OUT_BUS));
    android_device_map_.insert(std::make_pair(AUDIO_DEVICE_OUT_PROXY, PAL_DEVICE_OUT_PROXY));
    android_device_map_.insert(std::make_pair(AUDIO_DEVICE_OUT_USB_HEADSET, PAL_DEVICE_OUT_USB_HEADSET));
    android_device_map_.insert(std::make_pair(AUDIO_DEVICE_OUT_DEFAULT, PAL_DEVICE_OUT_SPEAKER));
    android_device_map_.insert(std::make_pair(AUDIO_DEVICE_OUT_HEARING_AID, PAL_DEVICE_OUT_HEARING_AID));
#ifdef USEHIDL7_1
    android_device_map_.insert(std::make_pair(AUDIO_DEVICE_OUT_BLE_BROADCAST, PAL_DEVICE_OUT_BLUETOOTH_BLE_BROADCAST));
#endif
    /* go through all in devices and pushback */

    android_device_map_.insert(std::make_pair(AUDIO_DEVICE_IN_BUILTIN_MIC, PAL_DEVICE_IN_HANDSET_MIC));
    android_device_map_.insert(std::make_pair(AUDIO_DEVICE_IN_BACK_MIC, PAL_DEVICE_IN_SPEAKER_MIC));
    //android_device_map_.insert(std::make_pair(AUDIO_DEVICE_IN_COMMUNICATION, PAL_DEVICE_IN_COMMUNICATION));
    //android_device_map_.insert(std::make_pair(AUDIO_DEVICE_IN_AMBIENT, PAL_DEVICE_IN_AMBIENT);
    android_device_map_.insert(std::make_pair(AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET, PAL_DEVICE_IN_BLUETOOTH_SCO_HEADSET));
    android_device_map_.insert(std::make_pair(AUDIO_DEVICE_IN_WIRED_HEADSET, PAL_DEVICE_IN_WIRED_HEADSET));
    android_device_map_.insert(std::make_pair(AUDIO_DEVICE_IN_AUX_DIGITAL, PAL_DEVICE_IN_AUX_DIGITAL));
    android_device_map_.insert(std::make_pair(AUDIO_DEVICE_IN_HDMI, PAL_DEVICE_IN_HDMI));
    //android_device_map_.insert(std::make_pair(AUDIO_DEVICE_IN_VOICE_CALL, PAL_DEVICE_IN_HANDSET_MIC));
    android_device_map_.insert(std::make_pair(AUDIO_DEVICE_IN_TELEPHONY_RX, PAL_DEVICE_IN_TELEPHONY_RX));
    //android_device_map_.insert(std::make_pair(AUDIO_DEVICE_IN_REMOTE_SUBMIX, PAL_DEVICE_IN_REMOTE_SUBMIX);
    //android_device_map_.insert(std::make_pair(AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET, PAL_DEVICE_IN_ANLG_DOCK_HEADSET);
    //android_device_map_.insert(std::make_pair(AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET, PAL_DEVICE_IN_DGTL_DOCK_HEADSET);
    android_device_map_.insert(std::make_pair(AUDIO_DEVICE_IN_USB_ACCESSORY, PAL_DEVICE_IN_USB_ACCESSORY));
    android_device_map_.insert(std::make_pair(AUDIO_DEVICE_IN_USB_DEVICE, PAL_DEVICE_IN_USB_HEADSET));
    android_device_map_.insert(std::make_pair(AUDIO_DEVICE_IN_FM_TUNER, PAL_DEVICE_IN_FM_TUNER));
    //android_device_map_.insert(std::make_pair(AUDIO_DEVICE_IN_TV_TUNER, PAL_DEVICE_IN_TV_TUNER);
    android_device_map_.insert(std::make_pair(AUDIO_DEVICE_IN_LINE, PAL_DEVICE_IN_LINE));
    android_device_map_.insert(std::make_pair(AUDIO_DEVICE_IN_SPDIF, PAL_DEVICE_IN_SPDIF));
    android_device_map_.insert(std::make_pair(AUDIO_DEVICE_IN_BLUETOOTH_A2DP, PAL_DEVICE_IN_BLUETOOTH_A2DP));
    android_device_map_.insert(std::make_pair(AUDIO_DEVICE_IN_BLE_HEADSET, PAL_DEVICE_IN_BLUETOOTH_BLE));
    //android_device_map_.insert(std::make_pair(AUDIO_DEVICE_IN_LOOPBACK, PAL_DEVICE_IN_LOOPBACK);
    //android_device_map_.insert(std::make_pair(AUDIO_DEVICE_IN_IP, PAL_DEVICE_IN_IP);
    //android_device_map_.insert(std::make_pair(AUDIO_DEVICE_IN_BUS, PAL_DEVICE_IN_BUS);
    android_device_map_.insert(std::make_pair(AUDIO_DEVICE_IN_PROXY, PAL_DEVICE_IN_PROXY));
    android_device_map_.insert(std::make_pair(AUDIO_DEVICE_IN_USB_HEADSET, PAL_DEVICE_IN_USB_HEADSET));
    //android_device_map_.insert(std::make_pair(AUDIO_DEVICE_IN_HDMI_ARC, PAL_DEVICE_IN_HDMI_ARC);
    //android_device_map_.insert(std::make_pair(AUDIO_DEVICE_IN_BLUETOOTH_BLE, PAL_DEVICE_IN_BLUETOOTH_BLE);
    //android_device_map_.insert(std::make_pair(AUDIO_DEVICE_IN_DEFAULT, PAL_DEVICE_IN_DEFAULT));
    android_device_map_.insert(std::make_pair(AUDIO_DEVICE_IN_ECHO_REFERENCE, PAL_DEVICE_IN_ECHO_REF));
}

int AudioDevice::GetPalDeviceIds(const std::set<audio_devices_t>& hal_device_ids,
                                 pal_device_id_t* pal_device_id) {
    int device_count = 0;
    if (!pal_device_id) {
        AHAL_ERR("invalid pal device id");
        goto error;
    }

    // pal device ids is supposed to have to space for the new ids
    AHAL_DBG("haldeviceIds: %zu", hal_device_ids.size());

    for(auto hal_device_id : hal_device_ids) {
        auto it = android_device_map_.find(hal_device_id);
        if (it != android_device_map_.end() &&
                audio_is_input_device(it->first) == audio_is_input_device(hal_device_id)) {
            AHAL_DBG("Found haldeviceId: %x and PAL Device ID %d",
                    it->first, it->second);
            if (it->second == PAL_DEVICE_OUT_AUX_DIGITAL ||
                    it->second == PAL_DEVICE_OUT_HDMI) {
               AHAL_DBG("dp_controller: %d dp_stream: %d",
                       dp_controller, dp_stream);
               if (dp_controller * MAX_STREAMS_PER_CONTROLLER + dp_stream) {
                  pal_device_id[device_count] = PAL_DEVICE_OUT_AUX_DIGITAL_1;
               } else {
                  pal_device_id[device_count] = it->second;
               }
            } else {
               pal_device_id[device_count] = it->second;
            }
        }
        ++device_count;
    }

error:
    AHAL_DBG("devices allocated %zu, pal device ids before returning %d",
             hal_device_ids.size(), device_count);
    return device_count;
}

void AudioDevice::SetChargingMode(bool is_charging) {
    int32_t result = 0;
    pal_param_charging_state_t charge_state;

    AHAL_DBG("enter, is_charging %d", is_charging);
    is_charging_ = is_charging;
    charge_state.charging_state = is_charging;

    result = pal_set_param(PAL_PARAM_ID_CHARGING_STATE, (void*)&charge_state,
                        sizeof(pal_param_charging_state_t));
    if (result)
        AHAL_DBG("error while handling charging event result(%d)\n",
                 result);

    AHAL_DBG("exit");
}

hw_device_t* AudioDevice::GetAudioDeviceCommon()
{
    return &(adev_->device_.get()->common);
}

static int adev_open(const hw_module_t *module, const char *name __unused,
                     hw_device_t **device) {
    int32_t ret = 0;
    AHAL_DBG("Enter");

    std::shared_ptr<AudioDevice> adevice = AudioDevice::GetInstance();

    if (!adevice) {
        AHAL_ERR("error, GetInstance failed");
    }

    adevice->adev_init_mutex.lock();
    if (adevice->adev_init_ref_count != 0) {
        *device = adevice->GetAudioDeviceCommon();
        adevice->adev_init_ref_count++;
        adevice->adev_init_mutex.unlock();
        AHAL_DBG("returning existing instance of adev, exiting");
        goto exit;
    }

    ret = adevice->Init(device, module);

    if (ret || (*device == NULL)) {
        AHAL_ERR("error, audio device init failed, ret(%d),*device(%p)",
                 ret, *device);
    }
    adevice->adev_init_mutex.unlock();
exit:
    AHAL_DBG("Exit, status %d", ret);
    return ret;
}

static struct hw_module_methods_t hal_module_methods = {
    .open = adev_open,
};

struct audio_module HAL_MODULE_INFO_SYM = {
    .common = {
        .tag = HARDWARE_MODULE_TAG,
        .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
        .hal_api_version = HARDWARE_HAL_API_VERSION,
        .id = AUDIO_HARDWARE_MODULE_ID,
        .name = "QTI Audio HAL",
        .author = "The Linux Foundation",
        .methods = &hal_module_methods,
    },
};

audio_patch_handle_t AudioPatch::generate_patch_handle_l() {
    static audio_patch_handle_t handles = AUDIO_PATCH_HANDLE_NONE;
    if (++handles < 0)
        handles = AUDIO_PATCH_HANDLE_NONE + 1;
    return handles;
}

AudioPatch::AudioPatch(PatchType patch_type,
                       const std::vector<struct audio_port_config>& sources,
                       const std::vector<struct audio_port_config>& sinks):
                       type(patch_type), sources(sources), sinks(sinks) {
        static std::mutex patch_lock;
        std::lock_guard<std::mutex> lock(patch_lock);
        handle = AudioPatch::generate_patch_handle_l();
}

bool AudioDevice::find_enum_by_string(const struct audio_string_to_enum * table, const char * name,
        int32_t len, unsigned int *value)
{
    if (table == NULL) {
        ALOGE("%s: table is NULL", __func__);
        return false;
    }

    if (name == NULL) {
        ALOGE("null key");
        return false;
    }

    for (int i = 0; i < len; i++) {
        if (!strcmp(table[i].name, name)) {
            *value = table[i].value;
            return true;
        }
    }
    return false;
}

bool AudioDevice::set_microphone_characteristic(struct audio_microphone_characteristic_t *mic)
{
    if (microphones.declared_mic_count >= AUDIO_MICROPHONE_MAX_COUNT) {
        AHAL_ERR("mic number is more than maximum number");
        return false;
    }
    for (size_t ch = 0; ch < AUDIO_CHANNEL_COUNT_MAX; ch++) {
        mic->channel_mapping[ch] = AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED;
    }
    microphones.microphone[microphones.declared_mic_count++] = *mic;
    return true;
}

int32_t AudioDevice::get_microphones(struct audio_microphone_characteristic_t *mic_array, size_t *mic_count)
{
    if (!mic_characteristics_available)
        return -EIO;

    if (mic_count == NULL) {
        AHAL_ERR("Invalid mic_count!!!");
        return -EINVAL;
    }
    if (mic_array == NULL) {
        AHAL_ERR("Invalid mic_array!!!");
        return -EINVAL;
    }

    if (*mic_count == 0) {
        AHAL_INFO("mic_count is ZERO");
        return 0;
    }

    size_t max_mic_count = *mic_count;
    size_t actual_mic_count = 0;
    for (size_t i = 0; i < max_mic_count && i < microphones.declared_mic_count; i++) {
        mic_array[i] = microphones.microphone[i];
        actual_mic_count++;
    }
    *mic_count = actual_mic_count;
    return 0;
}

void AudioDevice::process_microphone_characteristics(const XML_Char **attr)
{
    struct audio_microphone_characteristic_t microphone = {};
    uint32_t curIdx = 0;
    uint32_t valid_mask;

    if (strcmp(attr[curIdx++], "valid_mask")) {
        AHAL_ERR("valid_mask not found");
        goto done;
    }
    valid_mask = atoi(attr[curIdx++]);

    if (strcmp(attr[curIdx++], "device_id")) {
        AHAL_ERR("device_id not found");
        goto done;
    }
    if (strlen(attr[curIdx]) > AUDIO_MICROPHONE_ID_MAX_LEN) {
        AHAL_ERR("device_id is too long : %s ", attr[curIdx]);
        goto done;
    }
    strlcpy(microphone.device_id, attr[curIdx++], sizeof(microphone.device_id));

    if (strcmp(attr[curIdx++], "type")) {
        AHAL_ERR("device type not found");
        goto done;
    }
    if (!find_enum_by_string(device_in_types, (char*)attr[curIdx++],
                ARRAY_SIZE(device_in_types), (unsigned int *)(&microphone.device))) {
        AHAL_ERR("device type: %s not found", attr[--curIdx]);
        goto done;
    }
    if (strcmp(attr[curIdx++], "address")) {
        AHAL_ERR("address not found");
        goto done;
    }
    if (strlen(attr[curIdx]) > AUDIO_DEVICE_MAX_ADDRESS_LEN) {
        AHAL_ERR("address %s is too long", attr[curIdx]);
        goto done;
    }
    strlcpy(microphone.address, attr[curIdx++], sizeof(microphone.address));
    if (strlen(microphone.address) == 0) {
        // If the address is empty, populate the address according to device type.
        if (microphone.device == AUDIO_DEVICE_IN_BUILTIN_MIC) {
            strlcpy(microphone.address, AUDIO_BOTTOM_MICROPHONE_ADDRESS, sizeof(microphone.address));
        } else if (microphone.device == AUDIO_DEVICE_IN_BACK_MIC) {
            strlcpy(microphone.address, AUDIO_BACK_MICROPHONE_ADDRESS, sizeof(microphone.address));
        }
    }

    if (strcmp(attr[curIdx++], "location")) {
        AHAL_ERR("location not found");
        goto done;
    }
    if (!find_enum_by_string(mic_locations, (char*)attr[curIdx++],
                AUDIO_MICROPHONE_LOCATION_CNT, (unsigned int *)(&microphone.location))) {
        AHAL_ERR("location: %s not found", attr[--curIdx]);
        goto done;
    }

    if (strcmp(attr[curIdx++], "group")) {
        AHAL_ERR("group not found");
        goto done;
    }
    microphone.group = atoi(attr[curIdx++]);

    if (strcmp(attr[curIdx++], "index_in_the_group")) {
        AHAL_ERR("index_in_the_group not found");
        goto done;
    }
    microphone.index_in_the_group = atoi(attr[curIdx++]);

    if (strcmp(attr[curIdx++], "directionality")) {
        AHAL_ERR("directionality not found");
        goto done;
    }
    if (!find_enum_by_string(mic_directionalities, (char*)attr[curIdx++],
                AUDIO_MICROPHONE_DIRECTIONALITY_CNT, (unsigned int *)(&microphone.directionality))) {
        AHAL_ERR("directionality : %s not found", attr[--curIdx]);
        goto done;
    }

    if (strcmp(attr[curIdx++], "num_frequency_responses")) {
        AHAL_ERR("num_frequency_responses not found");
        goto done;
    }
    microphone.num_frequency_responses = atoi(attr[curIdx++]);
    if (microphone.num_frequency_responses > AUDIO_MICROPHONE_MAX_FREQUENCY_RESPONSES) {
        AHAL_ERR("num_frequency_responses is too large");
        goto done;
    }
    if (microphone.num_frequency_responses > 0) {
        if (strcmp(attr[curIdx++], "frequencies")) {
            AHAL_ERR("frequencies not found");
            goto done;
        }
        char *context = NULL;
        char *token = strtok_r((char *)attr[curIdx++], " ", &context);
        uint32_t num_frequencies = 0;
        while (token) {
            microphone.frequency_responses[0][num_frequencies++] = atof(token);
            if (num_frequencies >= AUDIO_MICROPHONE_MAX_FREQUENCY_RESPONSES) {
                break;
            }
            token = strtok_r(NULL, " ", &context);
        }

        if (strcmp(attr[curIdx++], "responses")) {
            AHAL_ERR("responses not found");
            goto done;
        }
        token = strtok_r((char *)attr[curIdx++], " ", &context);
        uint32_t num_responses = 0;
        while (token) {
            microphone.frequency_responses[1][num_responses++] = atof(token);
            if (num_responses >= AUDIO_MICROPHONE_MAX_FREQUENCY_RESPONSES) {
                break;
            }
            token = strtok_r(NULL, " ", &context);
        }

        if (num_frequencies != num_responses
                || num_frequencies != microphone.num_frequency_responses) {
            AHAL_ERR("num of frequency and response not match: %u, %u, %u",
                    num_frequencies, num_responses, microphone.num_frequency_responses);
            goto done;
        }
    }

    if (valid_mask & AUDIO_MICROPHONE_CHARACTERISTIC_SENSITIVITY) {
        if (strcmp(attr[curIdx++], "sensitivity")) {
            AHAL_ERR("sensitivity not found");
            goto done;
        }
        microphone.sensitivity = atof(attr[curIdx++]);
    } else {
        microphone.sensitivity = AUDIO_MICROPHONE_SENSITIVITY_UNKNOWN;
    }

    if (valid_mask & AUDIO_MICROPHONE_CHARACTERISTIC_MAX_SPL) {
        if (strcmp(attr[curIdx++], "max_spl")) {
            AHAL_ERR("max_spl not found");
            goto done;
        }
        microphone.max_spl = atof(attr[curIdx++]);
    } else {
        microphone.max_spl = AUDIO_MICROPHONE_SPL_UNKNOWN;
    }

    if (valid_mask & AUDIO_MICROPHONE_CHARACTERISTIC_MIN_SPL) {
        if (strcmp(attr[curIdx++], "min_spl")) {
            AHAL_ERR("min_spl not found");
            goto done;
        }
        microphone.min_spl = atof(attr[curIdx++]);
    } else {
        microphone.min_spl = AUDIO_MICROPHONE_SPL_UNKNOWN;
    }

    if (valid_mask & AUDIO_MICROPHONE_CHARACTERISTIC_ORIENTATION) {
        if (strcmp(attr[curIdx++], "orientation")) {
            AHAL_ERR("orientation not found");
            goto done;
        }
        char *context = NULL;
        char *token = strtok_r((char *)attr[curIdx++], " ", &context);
        float orientation[3];
        uint32_t idx = 0;
        while (token) {
            orientation[idx++] = atof(token);
            if (idx >= 3) {
                break;
            }
            token = strtok_r(NULL, " ", &context);
        }
        if (idx != 3) {
            AHAL_ERR("orientation invalid");
            goto done;
        }
        microphone.orientation.x = orientation[0];
        microphone.orientation.y = orientation[1];
        microphone.orientation.z = orientation[2];
    } else {
        microphone.orientation.x = 0.0f;
        microphone.orientation.y = 0.0f;
        microphone.orientation.z = 0.0f;
    }

    if (valid_mask & AUDIO_MICROPHONE_CHARACTERISTIC_GEOMETRIC_LOCATION) {
        if (strcmp(attr[curIdx++], "geometric_location")) {
            AHAL_ERR("geometric_location not found");
            goto done;
        }
        char *context = NULL;
        char *token = strtok_r((char *)attr[curIdx++], " ", &context);
        float geometric_location[3];
        uint32_t idx = 0;
        while (token) {
            geometric_location[idx++] = atof(token);
            if (idx >= 3) {
                break;
            }
            token = strtok_r(NULL, " ", &context);
        }
        if (idx != 3) {
            AHAL_ERR("geometric_location invalid");
            goto done;
        }
        microphone.geometric_location.x = geometric_location[0];
        microphone.geometric_location.y = geometric_location[1];
        microphone.geometric_location.z = geometric_location[2];
    } else {
        microphone.geometric_location.x = AUDIO_MICROPHONE_COORDINATE_UNKNOWN;
        microphone.geometric_location.y = AUDIO_MICROPHONE_COORDINATE_UNKNOWN;
        microphone.geometric_location.z = AUDIO_MICROPHONE_COORDINATE_UNKNOWN;
    }

    set_microphone_characteristic(&microphone);

done:
    return;
}

bool AudioDevice::is_input_pal_dev_id(int deviceId)
{
    if ((deviceId > PAL_DEVICE_IN_MIN) && (deviceId < PAL_DEVICE_IN_MAX))
        return true;

    return false;
}

void AudioDevice::process_snd_dev(const XML_Char **attr)
{
    uint32_t curIdx = 0;
    in_snd_device = PAL_DEVICE_NONE;

    if (strcmp(attr[curIdx++], "in_snd_device")) {
        AHAL_ERR("snd_device not found");
        return;
    }
    in_snd_device = deviceIdLUT.at((char *)attr[curIdx++]);
    if (!is_input_pal_dev_id(in_snd_device)) {
        AHAL_ERR("Sound device not valid");
        in_snd_device = PAL_DEVICE_NONE;
    }
    return;
}

bool AudioDevice::set_microphone_map(pal_device_id_t in_snd_device,
                                         const mic_info_t *info)
{
    uint32_t map_idx;
    uint32_t count;

    if (!is_input_pal_dev_id(in_snd_device)) {
        AHAL_ERR("Sound device not valid");
        return false;
    }

    map_idx = (MIC_INFO_MAP_INDEX(in_snd_device));
    count = microphone_maps[map_idx].mic_count++;
    if (count >= AUDIO_MICROPHONE_MAX_COUNT) {
        AHAL_ERR("Microphone count is greater than max allowed value");
        microphone_maps[map_idx].mic_count--;
        return false;
    }
    microphone_maps[map_idx].microphones[count] = *info;
    return true;
}

bool AudioDevice::is_built_in_input_dev(pal_device_id_t deviceId)
{
    if ((PAL_DEVICE_IN_HANDSET_MIC == deviceId) || (PAL_DEVICE_IN_SPEAKER_MIC == deviceId) ||
        (PAL_DEVICE_IN_HANDSET_VA_MIC == deviceId) || (PAL_DEVICE_IN_ULTRASOUND_MIC == deviceId))
        return true;

    return false;
}

void AudioDevice::process_mic_info(const XML_Char **attr)
{
    uint32_t curIdx = 0;
    mic_info_t microphone;
    char *context = NULL;
    uint32_t idx = 0;
    const char *token;

    memset(&microphone.channel_mapping, AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED,
                   sizeof(microphone.channel_mapping));

    if (strcmp(attr[curIdx++], "mic_device_id")) {
        AHAL_ERR("mic_device_id not found");
        goto on_error;
    }
    strlcpy(microphone.device_id, (char *)attr[curIdx++],
                            AUDIO_MICROPHONE_ID_MAX_LEN);

    if (strcmp(attr[curIdx++], "channel_mapping")) {
        AHAL_ERR("channel_mapping not found");
        goto on_error;
    }
    token = strtok_r((char *)attr[curIdx++], " ", &context);
    while (token) {
        if (!find_enum_by_string(mic_channel_mapping, token,
                    AUDIO_MICROPHONE_CHANNEL_MAPPING_CNT,
                    (unsigned int *)(&(microphone.channel_mapping[idx++])))) {
            AHAL_ERR("channel_mapping: %s not found", attr[--curIdx]);
            goto on_error;
        }
        token = strtok_r(NULL, " ", &context);
    }
    microphone.channel_count = idx;

    set_microphone_map(in_snd_device, &microphone);
    return;

on_error:
    in_snd_device = PAL_DEVICE_NONE;
    return;
}

int32_t AudioDevice::get_active_microphones(uint32_t channels, pal_device_id_t id,
                                            struct audio_microphone_characteristic_t *mic_array,
                                            uint32_t *mic_count)
{
    uint32_t actual_mic_count = 0;
    mic_info_t *m_info;
    uint32_t count = 0;
    uint32_t idx;
    uint32_t max_mic_count = microphones.declared_mic_count;

    if (!mic_characteristics_available)
        return -EIO;

    if (mic_count == NULL) {
        AHAL_ERR("Invalid mic_count!!!");
        return -EINVAL;
    }
    if (mic_array == NULL) {
        AHAL_ERR("Invalid mic_array!!!");
        return -EINVAL;
    }

    if (!is_input_pal_dev_id(id)) {
        AHAL_ERR("Invalid input sound device!!!");
        return -EINVAL;
    }

    if (*mic_count == 0) {
        AHAL_INFO("mic_count is ZERO");
        return 0;
    }

    if (is_input_pal_dev_id(id)) {
        idx = MIC_INFO_MAP_INDEX(id);
        count = microphone_maps[idx].mic_count;
        m_info = microphone_maps[idx].microphones;
        for (size_t i = 0; i < count; i++) {
            unsigned int channels_for_active_mic = channels;
            if (channels_for_active_mic > m_info[i].channel_count) {
                channels_for_active_mic = m_info[i].channel_count;
            }
            for (size_t j = 0; j < max_mic_count; j++) {
                if (strcmp(microphones.microphone[j].device_id,
                            m_info[i].device_id) == 0) {
                    mic_array[actual_mic_count] = microphones.microphone[j];
                    for (size_t ch = 0; ch < channels_for_active_mic; ch++) {
                        mic_array[actual_mic_count].channel_mapping[ch] =
                            m_info[i].channel_mapping[ch];
                    }
                    actual_mic_count++;
                    break;
                }
            }
        }
    }
    *mic_count = actual_mic_count;
    return 0;
}

void AudioDevice::xml_start_tag(void *userdata, const XML_Char *tag_name,
                         const XML_Char **attr)
{
    xml_userdata_t *data = (xml_userdata_t *)userdata;

    if (!strcmp(tag_name, "microphone")) {
        if (TAG_MICROPHONE_CHARACTERISTIC != data->tag) {
            AHAL_ERR("microphone tag only supported with MICROPHONE_CHARACTERISTIC section");
            return;
        }
        process_microphone_characteristics(attr);
        return;
    } else if (!strcmp(tag_name, "snd_dev")) {
        if (TAG_INPUT_SND_DEVICE_TO_MIC_MAPPING != data->tag) {
            AHAL_ERR("snd_dev tag only supported with INPUT_SND_DEVICE_TO_MIC_MAPPING section");
            return;
        }
        process_snd_dev(attr);
        return;
    } else if (!strcmp(tag_name, "mic_info")) {
        if (TAG_INPUT_SND_DEVICE_TO_MIC_MAPPING != data->tag) {
            AHAL_ERR("mic_info tag only supported with INPUT_SND_DEVICE_TO_MIC_MAPPING section");
            return;
        }
        if (PAL_DEVICE_NONE == in_snd_device) {
            AHAL_ERR("Error in previous tags, do not process mic info");
            return;
        }
        process_mic_info(attr);
        return;
    }

    if (!strcmp(tag_name, "microphone_characteristics")) {
        data->tag = TAG_MICROPHONE_CHARACTERISTIC;
    } else if (!strcmp(tag_name, "snd_devices")) {
        data->tag = TAG_SND_DEVICES;
    } else if (!strcmp(tag_name, "input_snd_device")) {
        if (TAG_SND_DEVICES != data->tag) {
            AHAL_ERR("input_snd_device tag only supported with SND_DEVICES section");
            return;
        }
        data->tag = TAG_INPUT_SND_DEVICE;
    } else if (!strcmp(tag_name, "input_snd_device_mic_mapping")) {
        if (TAG_INPUT_SND_DEVICE != data->tag) {
            AHAL_ERR("input_snd_device_mic_mapping tag only supported with INPUT_SND_DEVICE section");
            return;
        }
        data->tag = TAG_INPUT_SND_DEVICE_TO_MIC_MAPPING;;
    }
}

void AudioDevice::xml_end_tag(void *userdata, const XML_Char *tag_name)
{
    xml_userdata_t *data = (xml_userdata_t *)userdata;

    if (!strcmp(tag_name, "input_snd_device"))
        data->tag = TAG_SND_DEVICES;
    else if (!strcmp(tag_name, "input_snd_device_mic_mapping"))
        data->tag = TAG_INPUT_SND_DEVICE;
}

void AudioDevice::xml_char_data_handler(void *userdata, const XML_Char *s, int len)
{
   xml_userdata_t *data = (xml_userdata_t *)userdata;

   if (len + data->offs >= sizeof(data->data_buf) ) {
       data->offs += len;
       /* string length overflow, return */
       return;
   } else {
       memcpy(data->data_buf + data->offs, s, len);
       data->offs += len;
   }
}

int AudioDevice::parse_xml()
{
    XML_Parser parser;
    FILE *file = NULL;
    int ret = 0;
    int bytes_read;
    void *buf = NULL;
    xml_userdata_t xml_user_data;
    memset(&xml_user_data, 0, sizeof(xml_user_data));

    file = fopen(MIC_CHARACTERISTICS_XML_FILE, "r");
    if(!file) {
        ret = -EIO;
        AHAL_ERR("Failed to open xml file name %s", MIC_CHARACTERISTICS_XML_FILE);
        goto done;
    }

    parser = XML_ParserCreate(NULL);
    if (!parser) {
        ret = -EINVAL;
        AHAL_ERR("Failed to create XML parser ret %d", ret);
        goto closeFile;
    }
    XML_SetUserData(parser, &xml_user_data);
    XML_SetElementHandler(parser, xml_start_tag, xml_end_tag);
    XML_SetCharacterDataHandler(parser, xml_char_data_handler);

    while (1) {
        buf = XML_GetBuffer(parser, XML_READ_BUFFER_SIZE);
        if(buf == NULL) {
            ret = -EINVAL;
            AHAL_ERR("XML_Getbuffer failed ret %d", ret);
            goto freeParser;
        }

        bytes_read = fread(buf, 1, XML_READ_BUFFER_SIZE, file);
        if(bytes_read < 0) {
            ret = -EINVAL;
            AHAL_ERR("fread failed ret %d", ret);
            goto freeParser;
        }

        if(XML_ParseBuffer(parser, bytes_read, bytes_read == 0) == XML_STATUS_ERROR) {
            ret = -EINVAL;
            AHAL_ERR("XML ParseBuffer failed for %s file ret %d", MIC_CHARACTERISTICS_XML_FILE, ret);
            goto freeParser;
        }
        if (bytes_read == 0)
            break;
    }

freeParser:
    XML_ParserFree(parser);
closeFile:
    fclose(file);
    file = NULL;
done:
    return ret;
}
