/* sound_trigger_hw.c
 *
 * This file contains the API to load sound models with
 * DSP and start/stop detection of associated key phrases.
 *
 * Copyright (c) 2013-2021, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 *       copyright notice, this list of conditions and the following
 *       disclaimer in the documentation and/or other materials provided
 *       with the distribution.
 *     * Neither the name of The Linux Foundation nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Not a Contribution.
 *
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#define LOG_TAG "sound_trigger_hw"
#define ATRACE_TAG (ATRACE_TAG_HAL)
/* #define LOG_NDEBUG 0 */
#define LOG_NDDEBUG 0

#include <errno.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <fcntl.h>
#include <sys/resource.h>
#include <sys/prctl.h>
#include <sys/ioctl.h>
#include <cutils/log.h>
#include <cutils/atomic.h>
#include <cutils/trace.h>
#include <system/thread_defs.h>
#include <hardware/sound_trigger.h>
#include <cutils/str_parms.h>

#include "st_common_defs.h"
#include "sound_trigger_platform.h"
#include "sound_trigger_hw.h"
#include "st_session.h"
#include "st_hw_common.h"
#include "st_hw_extn.h"
#include "st_hw_defs.h"

#define XSTR(x) STR(x)
#define STR(x) #x

/* count of sound trigger hal clients */
static unsigned int stdev_ref_cnt = 0;
static pthread_mutex_t stdev_init_lock;
static struct sound_trigger_device *stdev = NULL;

static struct sound_trigger_properties_extended_1_3 hw_properties_extended;

/* default properties which will later be updated based on platform configuration */
static struct sound_trigger_properties hw_properties = {
        "QUALCOMM Technologies, Inc", // implementor
        "Sound Trigger HAL", // description
        1, // version
        { 0x68ab2d40, 0xe860, 0x11e3, 0x95ef, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } }, // uuid
        1, // max_sound_models
        1, // max_key_phrases
        1, // max_users
        RECOGNITION_MODE_VOICE_TRIGGER | RECOGNITION_MODE_GENERIC_TRIGGER, // recognition_modes
        true, // capture_transition
        0, // max_capture_ms
        false, // concurrent_capture
        false, //trigger_in_event
        0 // power_consumption_mw
};

/* vendor uuid that the client passes for LPMA feature */
static const sound_trigger_uuid_t lpma_uuid =
    { 0x57CADDB1, 0xACDB, 0x4DCE, 0x8CB0, { 0x2E, 0x95, 0xA2, 0x31, 0x3A, 0xEE } };

static void update_available_phrase_info(st_session_t *p_ses,
          struct sound_trigger_phrase_sound_model *phrase_sm,
          bool add);
static int stdev_reconfig_backend_on_stop(st_session_t *stopped_ses);

static int stop_recognition_l(st_session_t *st_session)
{
    int status = 0;

    st_session_stop_lab(st_session);
    status = st_session_stop(st_session);

    pthread_mutex_lock(&st_session->lock);
    st_session->callback = NULL;

    if (st_session->rc_config) {
        free(st_session->rc_config);
        st_session->rc_config = NULL;
    }
    if (st_session->st_conf_levels) {
        free(st_session->st_conf_levels);
        st_session->st_conf_levels = NULL;
    }

    pthread_mutex_unlock(&st_session->lock);
    stdev_reconfig_backend_on_stop(st_session);
    return status;
}

void update_hw_mad_exec_mode(st_exec_mode_t mode, st_profile_type_t profile_type)
{
    if (stdev->exec_mode != mode) {
        platform_stdev_connect_mad(stdev->platform, mode, profile_type);
        stdev->exec_mode = mode;
        ALOGV("%s: new exec_mode 0x%x", __func__, mode);
    }
}

unsigned int get_num_sessions()
{
    struct listnode *ses_node;
    st_session_t *p_ses;
    unsigned int num_sessions = 0;

    if ((list_head(&stdev->sound_model_list) == NULL) ||
                  (list_tail(&stdev->sound_model_list) == NULL)) {
        ALOGE("%s: sound model list is yet to be initialized", __func__);
        return num_sessions;
    }

    list_for_each(ses_node, &stdev->sound_model_list) {
        p_ses = node_to_item(ses_node, st_session_t, list_node);
            num_sessions++;
    }

    return num_sessions;
}

unsigned int get_num_sessions_in_exec_mode(st_exec_mode_t mode)
{
    struct listnode *ses_node;
    st_session_t *p_ses;
    unsigned int num_sessions = 0;

    if ((list_head(&stdev->sound_model_list) == NULL) ||
                  (list_tail(&stdev->sound_model_list) == NULL)) {
        ALOGE("%s: sound model list is yet to be initialized", __func__);
        return num_sessions;
    }

    list_for_each(ses_node, &stdev->sound_model_list) {
        p_ses = node_to_item(ses_node, st_session_t, list_node);
        if (p_ses->exec_mode == mode)
            num_sessions++;
    }

    return num_sessions;
}

static bool check_phrases_users_available(struct st_vendor_info *v_info,
    unsigned int num_phrases, unsigned int num_users,
    st_exec_mode_t exec_mode, bool transit)
{
    bool available = false;

    if (!v_info) {
        ALOGE("%s: NULL vendor info", __func__);
        return false;
    }

    if (!transit) {
        if (exec_mode == ST_EXEC_MODE_CPE) {
            if ((num_phrases <= v_info->avail_cpe_phrases) &&
                (num_users <= v_info->avail_cpe_users))
                available = true;
        }

        if (exec_mode == ST_EXEC_MODE_ADSP) {
            if ((num_phrases <= v_info->avail_ape_phrases) &&
                (num_users <= v_info->avail_ape_users))
                 available = true;
        }
    } else {
        if (exec_mode == ST_EXEC_MODE_CPE) {
            if ((num_phrases <= v_info->avail_transit_cpe_phrases) &&
                (num_users <= v_info->avail_transit_cpe_users))
                 available = true;
        }

        if (exec_mode == ST_EXEC_MODE_ADSP) {
            if ((num_phrases <= v_info->avail_transit_ape_phrases) &&
                (num_users <= v_info->avail_transit_ape_users))
                 available = true;
        }
    }

    ALOGV("%s: exec mode %d, transit %d, available %d",
           __func__, exec_mode, transit, available);
    return available;
}

static int parse_exec_mode_config(char *value,
                                  st_exec_mode_t *exec_mode,
                                  sound_model_handle_t *sm_handle)
{
    int ret = -EINVAL;
    char *id, *test_r;

    if (!value || !exec_mode || !sm_handle) {
        ALOGE("%s: Invalid params passed", __func__);
        return ret;
    }

    /*
     * <exec_mode>,<sound_model_handle>
     * sound model handle is optional. Valid set param values are:
     * 1. "0" -> exec mode is set and sound model handle to default value 0
     * 2. "1,2" -> exec mode and sound model handle are set to passed values
     * sound model handle as 0 is treated as a global set parameter.
     */

    id = strtok_r(value, ", ", &test_r);
    if (!id) {
        ALOGE("%s: incorrect exec mode passed", __func__);
        return ret;
    }
    *exec_mode = atoi(id);

    id = strtok_r(NULL, ", ", &test_r);
    if (!id) {
        ALOGD("%s: No session id passed, treat as global set param", __func__);
        *sm_handle = 0;
    } else {
        *sm_handle = atoi(id);
    }

    ALOGD("%s: mode %d, sm handle %d", __func__, *exec_mode, *sm_handle);
    return 0;
}

static bool is_any_session_buffering()
{
    struct listnode *p_ses_node;
    st_session_t *p_ses;

    list_for_each(p_ses_node, &stdev->sound_model_list) {
        p_ses = node_to_item(p_ses_node, st_session_t, list_node);
        if (st_session_is_buffering(p_ses)) {
            ALOGD("%s:[%d] session is buffering", __func__, p_ses->sm_handle);
            return true;
        }
    }
    return false;
}

static bool is_any_session_ssr_state()
{
    struct listnode *p_ses_node;
    st_session_t *p_ses;

    list_for_each(p_ses_node, &stdev->sound_model_list) {
        p_ses = node_to_item(p_ses_node, st_session_t, list_node);
        if (st_session_is_ssr_state(p_ses)) {
            ALOGD("%s:[%d] session is in ssr state", __func__, p_ses->sm_handle);
            return true;
        }
    }
    return false;
}

static int check_and_transit_cpe_ses_to_ape(st_session_t *cur_ses)
{
    st_session_t *p_ses = NULL;
    struct listnode *node = NULL;
    unsigned int num_sessions = 0;
    struct st_vendor_info *ses_v_info = NULL;
    struct listnode transit_sound_model_list;
    int ret = -EINVAL;

    /* Switch sessions from CPE to ADSP
     * 1. If cur_ses is NULL, all existing sessions are switched to ADSP.
     * 2. If cur_ses is valid, cur_ses is the session requested to transit.
     *    In such cases, switch sessions if they share same backend with
     *    cur_ses.
     */
    ALOGD("%s: enter: current ses %p", __func__, cur_ses);

    if (stdev->platform_lpi_enable != ST_PLATFORM_LPI_NONE) {
        ret = 0;
        goto exit;
    }

    if (0 == get_num_sessions_in_exec_mode(ST_EXEC_MODE_CPE)) {
        ret = 0;
        goto exit;
    }

    if (cur_ses && (cur_ses->exec_mode != ST_EXEC_MODE_CPE)) {
        ALOGE("%s: Invalid mode set for current session %d",
               __func__, cur_ses->exec_mode);
        goto exit;
    }

    /* Initialize transit ape phrases/users for all CPE sessions */
    list_for_each(node, &stdev->sound_model_list) {
        p_ses = node_to_item(node, st_session_t, list_node);
        if (p_ses->exec_mode == ST_EXEC_MODE_CPE) {
            ses_v_info = p_ses->vendor_uuid_info;
            ses_v_info->avail_transit_ape_phrases = ses_v_info->avail_ape_phrases;
            ses_v_info->avail_transit_ape_users = ses_v_info->avail_ape_users;
        }
    }

    list_init(&transit_sound_model_list);
    /*
     * check if the existing CPE sessions can be moved to ADSP
     * Add sessions to be switched to transit list.
     */
    list_for_each(node, &stdev->sound_model_list) {
        p_ses = node_to_item(node, st_session_t, list_node);
        if (p_ses->exec_mode == ST_EXEC_MODE_CPE) {
            /* check for sessions to keep on WDSP mode if requested by APP */
            if (ST_DET_LOW_POWER_MODE == p_ses->client_req_det_mode) {
                ALOGV("%s:[%d] session is requested on WDSP mode, skip",
                       __func__, p_ses->sm_handle);
                continue;
            }
            /* check for sessions that match backend with current session */
            if (cur_ses && (cur_ses != p_ses) &&
                !platform_stdev_check_backends_match(stdev->platform,
                                                  cur_ses->exec_mode,
                    cur_ses->hw_proxy_ses->hw_ses_current->st_device,
                                                    p_ses->exec_mode,
                    p_ses->hw_proxy_ses->hw_ses_current->st_device)) {
                ALOGV("%s:[%d] session not sharing backend",
                       __func__, p_ses->sm_handle);
                continue;
            }

            if (++num_sessions > stdev->max_ape_sessions) {
                ALOGE("%s: ERROR. sessions exceed max supported", __func__);
                goto exit;
            }

            ses_v_info = p_ses->vendor_uuid_info;
            if (ses_v_info->exec_mode_cfg != EXEC_MODE_CFG_DYNAMIC) {
                ALOGE("%s:[%d] ERROR. exec mode cfg %d not set to Dynamic",
                      __func__, p_ses->sm_handle, ses_v_info->exec_mode_cfg);
                goto exit;
            }

            if (p_ses->sm_type == SOUND_MODEL_TYPE_KEYPHRASE) {
                if (check_phrases_users_available(ses_v_info, p_ses->num_phrases,
                                  p_ses->num_users, ST_EXEC_MODE_ADSP, true)) {
                     ses_v_info->avail_transit_ape_phrases  -= p_ses->num_phrases;
                     ses_v_info->avail_transit_ape_users  -= p_ses->num_users;
                } else {
                    ALOGE("%s: ERROR. phrases/users exceed max supported", __func__);
                    goto exit;
                }
            }
            /* Add the session to transit sound models list */
            list_add_tail(&transit_sound_model_list,
                                   &p_ses->transit_list_node);
        }
    }

    ALOGV("%s: transit list empty: %s", __func__,
       list_empty(&transit_sound_model_list) ? "true" : "false");

    /*
     * During switching, below order is followed to ensure teardown
     * of all sessions happens first and then are started in new exec mode.
     * This helps avoid issues during multisession backend switching.
     * 1. Teardown the sessions by calling set_exec_mode with NONE.
     * 2. Bring up the sessions in ADSP mode.
     */

    /* Move sessions present in transit sound model list to NONE */
    list_for_each(node, &transit_sound_model_list) {
        p_ses = node_to_item(node, st_session_t, transit_list_node);

        if (p_ses->sm_type == SOUND_MODEL_TYPE_KEYPHRASE)
            update_available_phrase_info(p_ses, p_ses->phrase_sm, true);

        ALOGD("%s:[%d] switch session to NONE", __func__, p_ses->sm_handle);
        ret = st_session_set_exec_mode(p_ses, ST_EXEC_MODE_NONE);
        if (ret) {
            if (stdev->ssr_offline_received) {
                goto ssr_exit;
            } else {
                /* TODO: Handle error during transitions */
                ALOGE("%s:[%d] ERROR. could not set NONE", __func__, p_ses->sm_handle);
                goto exit;
            }
        }
    }

    /* Move sessions present in transit sound model list to ADSP */
    list_for_each(node, &transit_sound_model_list) {
        p_ses = node_to_item(node, st_session_t, transit_list_node);

        ALOGD("%s:[%d] switch session to ADSP mode", __func__, p_ses->sm_handle);
        ret = st_session_set_exec_mode(p_ses, ST_EXEC_MODE_ADSP);
        if (ret) {
            if (stdev->ssr_offline_received) {
                goto ssr_exit;
            } else {
                /* TODO: Handle error during transitions */
                ALOGE("%s:[%d] ERROR. could not set ADSP mode", __func__, p_ses->sm_handle);
                goto exit;
            }
        }

        if (p_ses->sm_type == SOUND_MODEL_TYPE_KEYPHRASE)
            update_available_phrase_info(p_ses, p_ses->phrase_sm, false);
    }

ssr_exit:
    /* Set target exec mode to be used during ssr online handling */
    list_for_each(node, &transit_sound_model_list) {
        p_ses = node_to_item(node, st_session_t, transit_list_node);
        p_ses->ssr_transit_exec_mode = ST_EXEC_MODE_ADSP;
    }
    sthw_extn_lpma_notify_event(LPMA_EVENT_TRANSIT_CPE_TO_APE);
exit:
    ALOGD("%s: exit: ret %d", __func__, ret);
    return ret;
}

static int check_and_transit_ape_ses_to_cpe(st_session_t *cur_ses)
{
    st_session_t *p_ses = NULL;
    struct listnode *node;
    unsigned int num_sessions = 0, max_sessions;
    struct st_vendor_info *ses_v_info = NULL;
    struct listnode transit_sound_model_list;
    int ret = -EINVAL;

    /* Switch sessions from ADSP to CPE
     * 1. If cur_ses is NULL, all existing sessions are switched to CPE.
     * 2. If cur_ses is valid, cur_ses is the session requested to transit.
     *    In such cases, switch sessions if they share same backend with
     *    cur_ses.
     */
    ALOGD("%s: enter: current ses %p", __func__, cur_ses);

    if (stdev->platform_lpi_enable != ST_PLATFORM_LPI_NONE) {
        ret = 0;
        goto exit;
    }

    if (0 == get_num_sessions_in_exec_mode(ST_EXEC_MODE_ADSP)) {
        ret = 0;
        goto exit;
    }

    if (cur_ses && (cur_ses->exec_mode != ST_EXEC_MODE_ADSP)) {
        ALOGE("%s: Invalid mode set for current session %d",
               __func__, cur_ses->exec_mode);
        goto exit;
    }

    max_sessions = stdev->max_wdsp_sessions;

    /* Initialize transit cpe phrases/users for all ADSP sessions */
    list_for_each(node, &stdev->sound_model_list) {
        p_ses = node_to_item(node, st_session_t, list_node);
        if (p_ses->exec_mode == ST_EXEC_MODE_ADSP) {
            ses_v_info = p_ses->vendor_uuid_info;
            ses_v_info->avail_transit_cpe_phrases = ses_v_info->avail_cpe_phrases;
            ses_v_info->avail_transit_cpe_users = ses_v_info->avail_cpe_users;
        }
    }

    list_init(&transit_sound_model_list);
    /*
     * check if the existing ADSP sessions can be moved to CPE
     * Add sessions to be switched to transit list.
     */
    list_for_each(node, &stdev->sound_model_list) {
        p_ses = node_to_item(node, st_session_t, list_node);
        if (p_ses->exec_mode == ST_EXEC_MODE_ADSP) {
            /* check for sessions to keep on ADSP mode if requested by APP */
            if (ST_DET_HIGH_PERF_MODE == p_ses->client_req_det_mode) {
                ALOGV("%s:[%d] session is requested on ADSP mode, skip",
                       __func__, p_ses->sm_handle);
                continue;
            }
            /* check for sessions that match backend with current session */
            if (cur_ses && (cur_ses != p_ses) &&
                !platform_stdev_check_backends_match(stdev->platform,
                                                  cur_ses->exec_mode,
                    cur_ses->hw_proxy_ses->hw_ses_current->st_device,
                                                    p_ses->exec_mode,
                    p_ses->hw_proxy_ses->hw_ses_current->st_device)) {
                ALOGV("%s:[%d] session not sharing backend",
                       __func__, p_ses->sm_handle);
                continue;
            }

            if (++num_sessions > max_sessions) {
                ALOGE("%s: ERROR. sessions exceed max supported", __func__);
                goto exit;
            }

            ses_v_info = p_ses->vendor_uuid_info;
            if (ses_v_info->exec_mode_cfg != EXEC_MODE_CFG_DYNAMIC) {
                ALOGE("%s: [%d] ERROR. exec mode cfg %d not set to Dynamic",
                      __func__, p_ses->sm_handle, ses_v_info->exec_mode_cfg);
                goto exit;
            }

            if (p_ses->sm_type == SOUND_MODEL_TYPE_KEYPHRASE) {
                if (check_phrases_users_available(ses_v_info, p_ses->num_phrases,
                                  p_ses->num_users, ST_EXEC_MODE_CPE, true)) {
                     ses_v_info->avail_transit_cpe_phrases  -= p_ses->num_phrases;
                     ses_v_info->avail_transit_cpe_users  -= p_ses->num_users;
                } else {
                    ALOGE("%s: ERROR. phrases/users exceed max supported", __func__);
                    goto exit;
                }
            }
            /* Add the session to transit sound models list */
            list_add_tail(&transit_sound_model_list,
                                   &p_ses->transit_list_node);
        }
    }

    ALOGV("%s: transit list empty: %s", __func__,
       list_empty(&transit_sound_model_list) ? "true" : "false");

    /*
     * During switching, below order is followed to ensure teardown
     * of all sessions happens first and then are started in new exec mode.
     * This helps avoid issues during multisession backend switching.
     * 1. Teardown the sessions by calling set_exec_mode with NONE.
     * 2. Bring up the sessions in CPE mode.
     */

    /* Move sessions present in transit sound model list to NONE */
    list_for_each(node, &transit_sound_model_list) {
        p_ses = node_to_item(node, st_session_t, transit_list_node);

        if (p_ses->sm_type == SOUND_MODEL_TYPE_KEYPHRASE)
            update_available_phrase_info(p_ses, p_ses->phrase_sm, true);

        ALOGD("%s:[%d] switch session to NONE", __func__, p_ses->sm_handle);
        ret = st_session_set_exec_mode(p_ses, ST_EXEC_MODE_NONE);
        if (ret) {
            if (stdev->ssr_offline_received) {
                goto ssr_exit;
            } else {
                /* TODO: Handle error during transitions */
                ALOGE("%s:[%d] ERROR. could not set NONE", __func__, p_ses->sm_handle);
                goto exit;
            }
        }
    }

    /* Move sessions present in transit sound model list to CPE */
    list_for_each(node, &transit_sound_model_list) {
        p_ses = node_to_item(node, st_session_t, transit_list_node);

        ALOGD("%s:[%d] switch session to CPE mode", __func__, p_ses->sm_handle);
        ret = st_session_set_exec_mode(p_ses, ST_EXEC_MODE_CPE);
        if (ret) {
            if (stdev->ssr_offline_received) {
                goto ssr_exit;
            } else {
                /* TODO: Handle error during transitions */
                ALOGE("%s:[%d] ERROR. could not set CPE mode", __func__, p_ses->sm_handle);
                goto exit;
            }
        }

        if (p_ses->sm_type == SOUND_MODEL_TYPE_KEYPHRASE)
            update_available_phrase_info(p_ses, p_ses->phrase_sm, false);
    }

ssr_exit:
    /* Set target exec mode to be used during ssr online handling */
    list_for_each(node, &transit_sound_model_list) {
        p_ses = node_to_item(node, st_session_t, transit_list_node);
        p_ses->ssr_transit_exec_mode = ST_EXEC_MODE_CPE;
    }
    sthw_extn_lpma_notify_event(LPMA_EVENT_TRANSIT_APE_TO_CPE);

exit:
    ALOGD("%s: exit: ret %d", __func__, ret);
    return ret;
}

static void notify_ssr_to_lpma(enum ssr_event_status event)
{
    enum sthw_extn_lpma_event_type lpma_event;

    switch (event) {
    case CPE_STATUS_OFFLINE:
        lpma_event = LPMA_EVENT_CPE_STATUS_OFFLINE;
        break;
    case CPE_STATUS_ONLINE:
        lpma_event = LPMA_EVENT_CPE_STATUS_ONLINE;
        break;
    case SLPI_STATUS_OFFLINE:
        lpma_event = LPMA_EVENT_SLPI_STATUS_OFFLINE;
        break;
    case SLPI_STATUS_ONLINE:
        lpma_event = LPMA_EVENT_SLPI_STATUS_ONLINE;
        break;
    default:
        return;
    }
    sthw_extn_lpma_notify_event(lpma_event);
}

static void handle_ssr_online(enum ssr_event_status event)
{
    struct listnode *p_ses_node;
    st_session_t *p_ses;

    ALOGD("%s: Enter", __func__);
    stdev->ssr_offline_received = false;
    ATRACE_BEGIN("sthal: handle_ssr_online");
    pthread_mutex_lock(&stdev->lock);

    /* Events allowed: SND_CARD ONLINE or CPE ONLINE */

    /*
     * During SSR offline, all the custom topology info is wiped off from
     * ADSP. Audio HAL can send these topologies during SSR online, but if
     * Audio Hal handles SSR online event later than sthal handles SSR
     * online, LSM session open fails with no matching topology found in
     * ADSP. Fix it by sending common custom topologies, that includes LSM
     * topologies, during SSR online.
     */
    if (event == SND_CARD_STATUS_ONLINE) {
        ALOGV("%s: sending common custom topology", __func__);
        if (platform_stdev_send_common_topology(stdev->platform))
            ALOGE("%s: sending common topology failed" ,__func__);
    }

    /* reload and reactive each previously active session */
    list_for_each(p_ses_node, &stdev->sound_model_list) {
        p_ses = node_to_item(p_ses_node, st_session_t, list_node);
        st_session_ssr_online(p_ses, event);
    }
    if (sthw_extn_lpma_present())
        notify_ssr_to_lpma(event);

    pthread_cond_broadcast(&stdev->cond);

    pthread_mutex_unlock(&stdev->lock);
    ATRACE_END();
    ALOGD("%s: Exit event %d", __func__, event);
}

static void handle_ssr_offline(enum ssr_event_status event)
{
    struct listnode *p_ses_node;
    st_session_t *p_ses;

    ALOGD("%s: Enter", __func__);
    stdev->ssr_offline_received = true;
    ATRACE_BEGIN("sthal: handle_ssr_offline");
    pthread_mutex_lock(&stdev->lock);

    /* Events allowed: SND_CARD OFFLINE or CPE OFFLINE */

    /* teardown each session */
    list_for_each(p_ses_node, &stdev->sound_model_list) {
        p_ses = node_to_item(p_ses_node, st_session_t, list_node);
        st_session_ssr_offline(p_ses, event);
    }
    if (sthw_extn_lpma_present())
        notify_ssr_to_lpma(event);

    pthread_mutex_unlock(&stdev->lock);
    ATRACE_END();
    ALOGD("%s: Exit event %d", __func__, event);
}

static void check_sessions_transition(audio_event_type_t event_type)
{
    int status;

    if ((AUDIO_EVENT_PLAYBACK_STREAM_ACTIVE == event_type) ||
        ((AUDIO_EVENT_BATTERY_STATUS_CHANGED == event_type) && stdev->is_charging)) {
        /* Transition to ADSP */
        if (is_any_session_buffering() ||
            is_any_session_ssr_state()) {
            stdev->transit_dir = TRANSIT_CPE_TO_APE;
            pthread_cond_signal(&stdev->transitions_cond);
        } else {
            status = check_and_transit_cpe_ses_to_ape(NULL);
            if (status)
                ALOGE("%s: Transition to ADSP failed, ignore", __func__);
        }
    } else if ((AUDIO_EVENT_PLAYBACK_STREAM_INACTIVE == event_type) ||
               ((AUDIO_EVENT_BATTERY_STATUS_CHANGED == event_type) && !stdev->is_charging)) {
        stdev->transit_dir = TRANSIT_APE_TO_CPE;
        pthread_cond_signal(&stdev->transitions_cond);
    }
}

static void handle_audio_ec_ref_enabled(audio_event_info_t* config)
{
    if (config == NULL) {
        ALOGE("%s: null config event received!", __func__);
        return;
    }
    ALOGD("%s: Enter", __func__);
    pthread_mutex_lock(&stdev->lock);
    stdev->audio_ec_enabled = config->u.audio_ec_ref_enabled;
    pthread_mutex_unlock(&stdev->lock);
    ALOGD("%s: Exit audio ec ref=%d", __func__, stdev->audio_ec_enabled);
}

static void handle_audio_concurrency(audio_event_type_t event_type,
    audio_event_info_t* config)
{
    struct listnode *p_ses_node = NULL, *node = NULL;
    st_session_t *p_ses = NULL;
    bool conc_allowed = false, lpi_changed = false, barge_in_mode = false;
    unsigned int num_sessions = 0;
    struct audio_device_info *item = NULL;

    if (config == NULL) {
        ALOGE("%s: Config is NULL, exiting", __func__);
        return;
    }

    list_for_each (node, &config->device_info.devices) {
        item = node_to_item(node, struct audio_device_info, list);
        ALOGV("%s: Audio device = 0x%x", __func__, item->type);
    }

    /*
    UC1:
        1. start_recognition
        2. audio record_active
        3. audio_record_inactive
        4. stop_recognition
    UC1:
        1. start_recognition
        2. audio record_active
        3. stop_recognition
        4. audio_record_inactive
    UC2:
        1. audio_record_active
        2. start_recognition
        3. stop_recogntion
        4. audio_record_inactive
    UC3:
        1. audio_record_active
        2. start_recognition
        3. audio_record_inactive
        4. stop_recogntion
    */
    pthread_mutex_lock(&stdev->lock);
    num_sessions = get_num_sessions();
    conc_allowed = platform_stdev_check_and_update_concurrency(stdev->platform,
        event_type, config, num_sessions);

    if (!conc_allowed)
        sthw_extn_lpma_notify_event(LPMA_EVENT_AUDIO_CONCURRENCY);

    if (!num_sessions) {
        stdev->session_allowed = conc_allowed;
        /*
         * This is needed for the following usecase:
         *
         * 1. LPI and NLPI have different number of MICs (different devices).
         * 2. ST session is stopped from app and unloaded while Tx active.
         * 3. Tx stops.
         * 4. ST session started again from app on LPI.
         *
         * The device disablement is missed in step 3 because the st_session was
         * deinitialized. Thus, it is handled here.
         */
        if (event_type == AUDIO_EVENT_CAPTURE_DEVICE_INACTIVE &&
            !platform_stdev_is_dedicated_sva_path(stdev->platform) &&
            platform_stdev_backend_reset_allowed(stdev->platform))
            platform_stdev_disable_stale_devices(stdev->platform);
        pthread_mutex_unlock(&stdev->lock);
        return;
    }
    if (stdev->transit_to_adsp_on_playback)
        check_sessions_transition(event_type);

    if (platform_stdev_is_dedicated_sva_path(stdev->platform)) {
        /*
         * When SVA has dedicated tx path, ignore capture events when concurrency
         * is allowed with this capture event.
         * But need to handle capture events to pause VA sessions when concurrency
         * is not allowed but previously allowed, and also do resume when concurrency
         * is allowed but previously not allowed.
         */
        if (event_type == AUDIO_EVENT_CAPTURE_DEVICE_INACTIVE ||
            event_type == AUDIO_EVENT_CAPTURE_DEVICE_ACTIVE ||
            event_type == AUDIO_EVENT_CAPTURE_STREAM_INACTIVE ||
            event_type == AUDIO_EVENT_CAPTURE_STREAM_ACTIVE) {
            if (conc_allowed != stdev->session_allowed) {
                stdev->session_allowed = conc_allowed;
                if (!conc_allowed) {
                    list_for_each(p_ses_node, &stdev->sound_model_list) {
                        p_ses = node_to_item(p_ses_node, st_session_t, list_node);
                        st_session_pause(p_ses);
                    }
                } else {
                    list_for_each(p_ses_node, &stdev->sound_model_list) {
                        p_ses = node_to_item(p_ses_node, st_session_t, list_node);
                        st_session_resume(p_ses);
                    }
                }
            } else {
                ALOGV("%s: Ignore capture events as sva has dedicated path", __func__);
            }
            if (!conc_allowed) {
                pthread_mutex_unlock(&stdev->lock);
                return;
            }
        }
    } else {
        /*
         * 1. When concurrency is NOT allowed, pause VA sessions.
         * 2. When concurrency is allowed on:
         *    a. audio capture enabling - do nothing as the tx paths can be shared
         *       for both VA and audio capture.
         *    b. audio capture disabling - due to tx path was previously disabled
         *       by audio capture usecase, so need to do session pause->resume
         *       to resume tx path.
         */
        if (!conc_allowed) {
            list_for_each(p_ses_node, &stdev->sound_model_list) {
                p_ses = node_to_item(p_ses_node, st_session_t, list_node);
                st_session_pause(p_ses);
            }
        } else {
            if (event_type == AUDIO_EVENT_CAPTURE_DEVICE_INACTIVE) {
                /*
                 * The reset_backend flag allows the backend device to be disabled. This should
                 * only be disallowed when in non-dedicated path mode and there is an active
                 * audio input stream.
                 */
                stdev->reset_backend = platform_stdev_backend_reset_allowed(stdev->platform);
                st_hw_check_and_update_lpi(stdev, p_ses);
                stdev->vad_enable = st_hw_check_vad_support(stdev, p_ses, stdev->lpi_enable);

                list_for_each(p_ses_node, &stdev->sound_model_list) {
                    p_ses = node_to_item(p_ses_node, st_session_t, list_node);
                    ALOGD("%s:[%d] Capture device is disabled, pause SVA session",
                          __func__, p_ses->sm_handle);
                    st_session_pause(p_ses);
                }
                /*
                 * This is needed when the session goes to loaded state, then
                 * LPI/NLPI switch happens due to Rx event.
                 */
                platform_stdev_disable_stale_devices(stdev->platform);
                list_for_each(p_ses_node, &stdev->sound_model_list) {
                    p_ses = node_to_item(p_ses_node, st_session_t, list_node);
                    ALOGD("%s:[%d] Capture device is disabled, resume SVA session",
                          __func__, p_ses->sm_handle);
                    st_session_resume(p_ses);
                }
            } else if (event_type == AUDIO_EVENT_CAPTURE_DEVICE_ACTIVE) {
                ALOGD("Audio HAL has a capture session ON, don't disable the device");
            }
        }
        stdev->session_allowed = conc_allowed;
        if (!conc_allowed) {
            pthread_mutex_unlock(&stdev->lock);
            return;
        }
    }

    /*
     * lpi/vad decision might have changed based on the capture and playback
     * usecases becoming active/inactive. So check and update the lpi/vad
     * configuration which will be used during device backend setting as part
     * of session's start/resume.
     */
    barge_in_mode = stdev->barge_in_mode;
    st_hw_check_and_update_lpi(stdev, p_ses);
    lpi_changed = stdev->lpi_enable != platform_get_lpi_mode(stdev->platform);
    stdev->vad_enable = st_hw_check_vad_support(stdev, p_ses, stdev->lpi_enable);

    /*
     * Usecase 1: Playback enabled without display on/battery charging:
     *            lpi_changed = true, so transition occurs.
     * Usecase 2: Playback enabled with display on/battery charging:
     *            lpi_changed = false, and barge_in_mode changes from false to
     *            true. Dynamic EC update or transition will occur depending
     *            on the flag.
     * Usecase 3: Playback disabled without display on/battery charging:
     *            lpi_changed = true, so transition occurs.
     * Usecase 4: Playback disabled with display on/battery charging:
     *            lpi_changed = false, and barge_in_mode changes from true to
     *            false. Dynamic EC update or transition will occur depending
     *            on the flag.
     */
    if ((lpi_changed || barge_in_mode != stdev->barge_in_mode) &&
        !is_any_session_buffering()) {
        if (!lpi_changed && stdev->support_dynamic_ec_update) {
            platform_stdev_update_ec_effect(stdev->platform,
                stdev->barge_in_mode);
        } else {
            list_for_each(p_ses_node, &stdev->sound_model_list) {
                p_ses = node_to_item(p_ses_node, st_session_t, list_node);
                if (p_ses && p_ses->exec_mode == ST_EXEC_MODE_ADSP) {
                    ALOGD("%s:[%d] LPI: pause SVA session",
                        __func__, p_ses->sm_handle);
                    st_session_pause(p_ses);
                }
            }

            list_for_each(p_ses_node, &stdev->sound_model_list) {
                p_ses = node_to_item(p_ses_node, st_session_t, list_node);
                if (p_ses && p_ses->exec_mode == ST_EXEC_MODE_ADSP) {
                    ALOGD("%s:[%d] LPI: resume SVA session",
                        __func__, p_ses->sm_handle);
                    st_session_resume(p_ses);
                }
            }
        }
    }
    /*
     * The device can be disabled within this thread upon reception of the device
     * active event because audio hal does not enable the device until after returning
     * from this callback. After this thread exits, device disablement will be
     * disallowed until the device inactive event is received.
     */
    if (event_type == AUDIO_EVENT_CAPTURE_DEVICE_ACTIVE &&
        !platform_stdev_is_dedicated_sva_path(stdev->platform))
        stdev->reset_backend = platform_stdev_backend_reset_allowed(stdev->platform);
    pthread_mutex_unlock(&stdev->lock);
    ALOGV("%s: Exit", __func__);
}

static void *transitions_thread_loop(void * context __unused)
{
    int status = 0;
    int in_ssr = 0, ssr_retry = 0;
    /*
     *  This thread is used for audio playback transitions from ADSP
     *  to WDSP. This is needed for hotword detections on ADSP because
     *  the app pauses music playback during buffering and resumes when
     *  buffering stops. An audio playback inactive event sends the
     *  signal to this thread to begin looping while playback is paused.
     *  When both buffering and and audio playback are inactive, it is
     *  assumed to be a stoppage of audio playback NOT due to a hotword
     *  detection.
     *  This also handles battery charging use case, when the battery
     *  is not in charging status, sessions need to be transited back
     *  to WDSP.
     *  These two cases will transition to WDSP.
     */
    pthread_mutex_lock(&stdev->lock);
    if (stdev->transit_wait_time <= 0)
        stdev->transit_wait_time = TRANSIT_MIN_SLEEP_TIME_SEC;

    while (!stdev->stop_transitions_thread_loop) {
        /* Avoid spurious wake ups unncessarily acquiring wakelock later */
        while ((stdev->transit_dir == TRANSIT_NONE) &&
               !stdev->stop_transitions_thread_loop)
            pthread_cond_wait(&stdev->transitions_cond, &stdev->lock);
        if (stdev->stop_transitions_thread_loop) {
            pthread_mutex_unlock(&stdev->lock);
            return NULL;
        }
        acquire_wake_lock(PARTIAL_WAKE_LOCK, TRANSIT_WAKE_LOCK_NAME);
        ssr_retry = TRANSIT_SSR_TIMEOUT_SEC / stdev->transit_wait_time;
        if (stdev->transit_dir == TRANSIT_APE_TO_CPE) {
            while (1) {
                pthread_mutex_unlock(&stdev->lock);
                sleep(stdev->transit_wait_time);
                pthread_mutex_lock(&stdev->lock);
                bool keep_ape_mode = (stdev->rx_concurrency_active &&
                                      stdev->transit_to_adsp_on_playback) ||
                                     (stdev->is_charging &&
                                      stdev->transit_to_adsp_on_battery_charging);
                if (stdev->transit_dir != TRANSIT_APE_TO_CPE) {
                    ALOGD("transit_dir change to %d", stdev->transit_dir);
                    goto release_wl;
                } else if (keep_ape_mode) {
                    ALOGD("%s:No need to transit to CPE", __func__);
                    stdev->transit_dir = TRANSIT_NONE;
                    goto release_wl;
                }

                in_ssr = is_any_session_ssr_state();
                if (!is_any_session_buffering() &&
                    !in_ssr) {
                    /* Transition to WDSP */
                    ATRACE_BEGIN("sthal: check_and_transit_ape_ses_to_cpe");
                    status = check_and_transit_ape_ses_to_cpe(NULL);
                    ATRACE_END();
                    if (status)
                        ALOGE("%s: Transition to WDSP failed, ignore", __func__);
                    stdev->transit_dir = TRANSIT_NONE;
                    break;
                } else if (in_ssr && (ssr_retry-- <= 0)) {
                    ALOGE("%s: can't transit to cpe due to ssr", __func__);
                    stdev->transit_dir = TRANSIT_NONE;
                    goto release_wl;
                }
            }
            /*
             * It is possible that another rx is active or device is charging
             * before entering while loop which doesn't require transit to cpe.
             * Go back and wait for next transit event which will be not charging
             * or rx inactive -> transit to ape.
             */
        } else if (stdev->transit_dir == TRANSIT_CPE_TO_APE) {
            while (1) {
                pthread_mutex_unlock(&stdev->lock);
                sleep(stdev->transit_wait_time);
                pthread_mutex_lock(&stdev->lock);

                if (stdev->transit_dir != TRANSIT_CPE_TO_APE) {
                    ALOGD("transit_dir change to %d", stdev->transit_dir);
                    goto release_wl;
                }

                in_ssr = is_any_session_ssr_state();
                if (!is_any_session_buffering() && !in_ssr) {
                    /* Transition to ADSP */
                    ATRACE_BEGIN("sthal: check_and_transit_cpe_ses_to_ape");
                    status = check_and_transit_cpe_ses_to_ape(NULL);
                    ATRACE_END();
                    if (status)
                        ALOGE("%s: Transition to ADSP failed, ignore", __func__);
                    stdev->transit_dir = TRANSIT_NONE;
                    break;
                } else if (in_ssr && (ssr_retry-- <= 0)) {
                    ALOGE("%s: can't transit to ape due to ssr", __func__);
                    stdev->transit_dir = TRANSIT_NONE;
                    goto release_wl;
                }
            }
        } else {
            ALOGE("%s: Invalid transit direction %d", __func__, stdev->transit_dir);
        }
    release_wl:
        release_wake_lock(TRANSIT_WAKE_LOCK_NAME);
    }
    pthread_mutex_unlock(&stdev->lock);
    return NULL;
}

static void init_transitions_thread()
{
    int status = 0;

    stdev->stop_transitions_thread_loop = false;
    stdev->transit_dir = TRANSIT_NONE;
    status = pthread_create(&stdev->transitions_thread, NULL,
        transitions_thread_loop, NULL);
    if (status)
        ALOGE("%s: Error creating transitions thread. status = %d",
            __func__, status);
}

static void switch_device()
{
    struct listnode *p_ses_node = NULL;
    st_session_t *p_ses = NULL;

    if (!get_num_sessions()) {
        ALOGV("%s: no sessions remaining, exiting", __func__);
        return;
    }

    /* Start switching the device.
     * Disable all use cases followed by disabling the current device.
     * Enable new device followed by enabling all use cases .
     */
    list_for_each(p_ses_node, &stdev->sound_model_list) {
        p_ses = node_to_item(p_ses_node, st_session_t, list_node);
        st_session_disable_device(p_ses);
    }
    sthw_extn_lpma_notify_event(LPMA_EVENT_DISABLE_DEVICE);

    list_for_each(p_ses_node, &stdev->sound_model_list) {
        p_ses = node_to_item(p_ses_node, st_session_t, list_node);
        st_session_enable_device(p_ses);
    }
    sthw_extn_lpma_notify_event(LPMA_EVENT_ENABLE_DEVICE);
}

static void handle_device_switch(bool connect, audio_event_info_t* config)
{
    audio_devices_t device = config->u.value;
    audio_devices_t cur_device = 0;

    cur_device = platform_stdev_get_capture_device(stdev->platform);

    ALOGD("%s: device 0x%x %s", __func__, device,
          connect? "Connected":"Disconnected");
    ATRACE_BEGIN("sthal: handle_device_switch");

    if (!stdev->support_dev_switch ||
        !ST_CAPTURE_DEVICE_IS_SUPPORTED(device)) {
        ATRACE_END();
        ALOGV("%s: unsupported", __func__);
        return;
    }

    pthread_mutex_lock(&stdev->lock);

    /* Update this device to available list of internal devices. At the time
     * of enabling the device for a use case, actual device will be selected
     * based on internal device selection policy
     */
    platform_stdev_update_device_list(device, "", &stdev->available_devices,
        connect);

    if ((connect && (cur_device == device)) ||
         (!connect && (cur_device != device))) {
        ATRACE_END();
        ALOGV("%s: device 0x%x already %s", __func__,
              device, connect ? "enabled" : "disabled");
        pthread_mutex_unlock(&stdev->lock);
        return;
    }
    /*
     * If buffering or audio concurrency present, device switch will
     * interrupt and happen anyway. Session will already be in the loaded
     * state so device switch will set up the next session with the
     * new device to be started later
     */
    switch_device();

    pthread_mutex_unlock(&stdev->lock);
    ATRACE_END();
    ALOGV("%s: Exit", __func__);
}

static void handle_screen_status_change(audio_event_info_t* config)
{
    unsigned int num_sessions = 0;
    struct listnode *p_ses_node = NULL;
    st_session_t *p_ses = NULL;

    pthread_mutex_lock(&stdev->lock);
    stdev->screen_off = config->u.value;
    ALOGD("%s: screen %s", __func__, stdev->screen_off ? "off" : "on");

    num_sessions = get_num_sessions();
    if (!num_sessions) {
        pthread_mutex_unlock(&stdev->lock);
        return;
    }

    st_hw_check_and_update_lpi(stdev, p_ses);

    if (stdev->lpi_enable != platform_get_lpi_mode(stdev->platform) &&
        !is_any_session_buffering() && stdev->session_allowed) {
        list_for_each(p_ses_node, &stdev->sound_model_list) {
            p_ses = node_to_item(p_ses_node, st_session_t, list_node);
            if (p_ses && p_ses->exec_mode == ST_EXEC_MODE_ADSP) {
                ALOGD("%s:[%d] LPI: pause SVA session",
                    __func__, p_ses->sm_handle);
                st_session_pause(p_ses);
            }
        }

        list_for_each(p_ses_node, &stdev->sound_model_list) {
            p_ses = node_to_item(p_ses_node, st_session_t, list_node);
            if (p_ses && p_ses->exec_mode == ST_EXEC_MODE_ADSP) {
                ALOGD("%s:[%d] LPI: resume SVA session",
                    __func__, p_ses->sm_handle);
                st_session_resume(p_ses);
            }
        }
    }
    pthread_mutex_unlock(&stdev->lock);
    ALOGV("%s: Exit", __func__);
}

static void handle_battery_status_change(audio_event_info_t* config)
{
    unsigned int num_sessions;
    struct listnode *p_ses_node = NULL;
    st_session_t *p_ses = NULL;

    pthread_mutex_lock(&stdev->lock);
    stdev->is_charging = config->u.value;
    ALOGD("%s: battery status changed to %d", __func__, stdev->is_charging);

    num_sessions = get_num_sessions();
    if (!num_sessions) {
        pthread_mutex_unlock(&stdev->lock);
        return;
    }

    if (stdev->transit_to_adsp_on_battery_charging)
        check_sessions_transition(AUDIO_EVENT_BATTERY_STATUS_CHANGED);

    /*
     * lpi/vad decision might have changed based on the battery status change.
     * So check and update the lpi/vad configuration which will be used during
     * device backend setting as part of session's start/resume.
     */
    st_hw_check_and_update_lpi(stdev, p_ses);
    stdev->vad_enable = st_hw_check_vad_support(stdev, p_ses,
        stdev->lpi_enable);
    if (stdev->lpi_enable != platform_get_lpi_mode(stdev->platform) &&
        !is_any_session_buffering() && stdev->session_allowed &&
        stdev->transit_to_non_lpi_on_battery_charging) {
        list_for_each(p_ses_node, &stdev->sound_model_list) {
            p_ses = node_to_item(p_ses_node, st_session_t, list_node);
            if (p_ses && p_ses->exec_mode == ST_EXEC_MODE_ADSP) {
                ALOGD("%s:[%d] LPI: pause SVA session",
                    __func__, p_ses->sm_handle);
                st_session_pause(p_ses);
            }
        }

        list_for_each(p_ses_node, &stdev->sound_model_list) {
            p_ses = node_to_item(p_ses_node, st_session_t, list_node);
            if (p_ses && p_ses->exec_mode == ST_EXEC_MODE_ADSP) {
                ALOGD("%s:[%d] LPI: resume SVA session",
                    __func__, p_ses->sm_handle);
                st_session_resume(p_ses);
            }
        }
    }
    pthread_mutex_unlock(&stdev->lock);
    ALOGV("%s: Exit", __func__);
}

static void handle_echo_ref_switch(audio_event_type_t event_type,
                                   audio_event_info_t* config)
{
    struct listnode *node = NULL;
    st_session_t *p_ses = NULL;

    if (config == NULL) {
        ALOGV("%s: null config event received!", __func__);
        return;
    }

    pthread_mutex_lock(&stdev->lock);
    if (AUDIO_EVENT_PLAYBACK_STREAM_ACTIVE == event_type &&
        !platform_stdev_compare_devices(&config->device_info.devices,
            &stdev->active_rx_dev_list)) {
        /*
         * if currently no active ADSP session available, then echo
         * reference will be enabled during session transition
         */
        platform_stdev_assign_devices(&stdev->active_rx_dev_list,
            &config->device_info.devices);
        if (get_num_sessions_in_exec_mode(ST_EXEC_MODE_ADSP) > 0 &&
            (platform_stdev_is_a2dp_out_device_type(
                 &stdev->active_rx_dev_list) ||
             platform_stdev_compare_device_type(&stdev->active_rx_dev_list,
                 AUDIO_DEVICE_OUT_LINE) ||
             platform_stdev_compare_device_type(&stdev->active_rx_dev_list,
                 AUDIO_DEVICE_OUT_SPEAKER) ||
             platform_stdev_compare_device_type(&stdev->active_rx_dev_list,
                 AUDIO_DEVICE_IN_WIRED_HEADSET)) &&
             stdev->session_allowed) {
            /* pause and resume ADSP sessions to send new echo reference */
            list_for_each(node, &stdev->sound_model_list) {
                ALOGD("%s: Pause and resume sessions", __func__);
                p_ses = node_to_item(node, st_session_t, list_node);
                if (p_ses->exec_mode == ST_EXEC_MODE_ADSP) {
                    st_session_pause(p_ses);
                    st_session_resume(p_ses);
                }
            }
        }
    }
    pthread_mutex_unlock(&stdev->lock);
}

static void get_base_properties(struct sound_trigger_device *stdev)
{
    ALOGI("%s: enter", __func__);

    stdev->hw_properties->concurrent_capture = stdev->conc_capture_supported;

    /*
     * This hal interface API is not suitable to a granular level of reporting
     * individual max sound models based on different execution modes from
     * platform XML file. For ex: reporting lower no. of sound models meant for
     * WDSP mode results in framework not allowing more sound models which can
     * be supported for ADSP mode. Hence always report max sound models out of
     * all executions modes. At the max, the framework's error handling will be
     * delegated to sthal level, where sthal returns error if sound model
     * sessions exceed the platform supported for a given execution mode.
     */
    stdev->hw_properties->max_sound_models = MAX(stdev->max_wdsp_sessions,
        stdev->max_ape_sessions);
    stdev->hw_properties->max_key_phrases = MAX(stdev->avail_cpe_phrases,
        stdev->avail_ape_phrases);
    stdev->hw_properties->max_users = MAX(stdev->avail_cpe_users,
        stdev->avail_ape_users);
    stdev->hw_properties->max_buffer_ms = ST_GRAPHITE_LAB_BUF_DURATION_MS;

    ALOGVV("%s version=0x%x recognition_modes=%d, capture_transition=%d, "
           "concurrent_capture=%d", __func__, stdev->hw_properties->version,
           stdev->hw_properties->recognition_modes,
           stdev->hw_properties->capture_transition,
           stdev->hw_properties->concurrent_capture);

    memset(&hw_properties_extended, 0, sizeof(hw_properties_extended));
    memcpy(&hw_properties_extended.base, stdev->hw_properties,
           sizeof(struct sound_trigger_properties));
}

static int stdev_get_properties(const struct sound_trigger_hw_device *dev,
    struct sound_trigger_properties *properties)
{
    struct sound_trigger_device *stdev = (struct sound_trigger_device *)dev;

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

    get_base_properties(stdev);
    memcpy(properties, &hw_properties_extended.base, sizeof(struct sound_trigger_properties));
    hw_properties_extended.header.version = SOUND_TRIGGER_DEVICE_API_VERSION_1_0;
    return 0;
}

static st_exec_mode_t get_session_exec_mode
(
    st_session_t *p_ses,
    struct sound_trigger_sound_model *common_sm
)
{
    unsigned int num_sessions = 0;
    unsigned int num_users = 0;
    unsigned int num_phrases = 0;
    unsigned int i, j;
    st_exec_mode_t exec_mode = ST_EXEC_MODE_NONE;
    struct st_vendor_info *v_info = p_ses->vendor_uuid_info;
    struct sound_trigger_phrase_sound_model *phrase_sm = NULL;

    if (v_info == NULL)
        return ST_EXEC_MODE_NONE;

    num_sessions = get_num_sessions();

    if (common_sm->type == SOUND_MODEL_TYPE_KEYPHRASE) {
        phrase_sm = (struct sound_trigger_phrase_sound_model *)common_sm;
        num_phrases = phrase_sm->num_phrases;

        for (i = 0; i < phrase_sm->num_phrases; i++) {
            for (j = 0; j < phrase_sm->phrases[i].num_users; j++) {
                num_users++;
            }
        }
        p_ses->num_phrases = num_phrases;
        p_ses->num_users = num_users;

        ALOGD("%s: mode=%d NS=%d RKW=%u RU=%u VACKW=%u VACU=%u VADKW=%d, VADU=%d",
              __func__, v_info->exec_mode_cfg, num_sessions, num_phrases, num_users,
              v_info->avail_cpe_phrases, v_info->avail_cpe_users,
              v_info->avail_ape_phrases, v_info->avail_ape_users);
    }

    /*
     * Each algorithm can be configured to either CPE, ADSP or DYNAMIC
     * in the vendor info, if vendor info is present use it to determine
     * exec_mode
     */
    if (v_info->exec_mode_cfg == EXEC_MODE_CFG_CPE) {
        /* Algorithm configured for CPE only */
        if (num_sessions < stdev->max_wdsp_sessions) {
            if (common_sm->type == SOUND_MODEL_TYPE_KEYPHRASE) {
                /* Keyphrase sound model */
                if (check_phrases_users_available(v_info, num_phrases,
                                  num_users, ST_EXEC_MODE_CPE, false))
                    exec_mode = ST_EXEC_MODE_CPE;
            } else {
                /* Generic sound model without keyphrases */
                exec_mode = ST_EXEC_MODE_CPE;
            }
        }
    } else if (v_info->exec_mode_cfg == EXEC_MODE_CFG_APE) {
        if (num_sessions < stdev->max_ape_sessions) {
            if (common_sm->type == SOUND_MODEL_TYPE_KEYPHRASE) {
                if (check_phrases_users_available(v_info, num_phrases,
                                 num_users, ST_EXEC_MODE_ADSP, false))
                    exec_mode = ST_EXEC_MODE_ADSP;
            } else {
                exec_mode = ST_EXEC_MODE_ADSP;
            }
        }
    } else if (v_info->exec_mode_cfg == EXEC_MODE_CFG_DYNAMIC) {
        /*
         * If execution type is DYNAMIC, there are two cases:
         * 1)  Exec mode is dictated by explicit commands from the app.
         *     This comes from stdev->client_req_exec_mode.
         * 2)  If the app is not giving explicit exec mode commands, exec
         *     mode is determined by the state of active audio playback in
         *     accordance with the playback transitions functionality.
         */
        if (stdev->client_req_exec_mode == ST_EXEC_MODE_CPE) {
            /*
             * Check if the session can run on CPE, if client requested
             * CPE mode for all sessions.
             */
            ALOGV("%s: EXEC_MODE_CFG_DYNAMIC: req exec mode CPE", __func__);
            if (num_sessions < stdev->max_wdsp_sessions) {
                if (common_sm->type == SOUND_MODEL_TYPE_KEYPHRASE) {
                    /* Keyphrase sound model */
                    if (check_phrases_users_available(v_info, num_phrases,
                                      num_users, ST_EXEC_MODE_CPE, false))
                        exec_mode = ST_EXEC_MODE_CPE;
                } else {
                    /* Generic sound model without keyphrases */
                    exec_mode = ST_EXEC_MODE_CPE;
                }
            }
        } else if (stdev->client_req_exec_mode == ST_EXEC_MODE_ADSP) {
            /*
             * Check if the session can run on ADSP, if client requested
             * ADSP mode for all sessions.
             */
            ALOGV("%s: EXEC_MODE_CFG_DYNAMIC: req exec mode ADSP", __func__);
            if (num_sessions < stdev->max_ape_sessions) {
                if (common_sm->type == SOUND_MODEL_TYPE_KEYPHRASE) {
                    if (check_phrases_users_available(v_info, num_phrases,
                                     num_users, ST_EXEC_MODE_ADSP, false))
                        exec_mode = ST_EXEC_MODE_ADSP;
                } else {
                    exec_mode = ST_EXEC_MODE_ADSP;
                }
            }
        } else {
            /*
             * client_req_exec_mode is NONE.
             * In this case, check:
             * 1. If audio playback transitions are enabled
             *    and if audio playback is currently active.
             * 2. If battery charging transitions are enabled
             *    and if battery is in charging
             * If either of the criteria are satisfied, try on ADSP and error
             * out if the new session cannot be started on it. If they are not
             * satisfied, try on CPE and error out if the new session cannot be
             * started on it.
             *
             * TODO -
             * client requested exec mode can be NONE if transition was
             * requested for a particular session i.e. not a global transition.
             * In cases where transition was requested per session, two cases
             * arise for a newly started session:
             * 1. The new session’s backend does not match with the sessions
             *    that have been switched and can run independent of them.
             * 2. The session’s backend matches with the sessions that have
             *    been switched above.
             * Since st_device is not available at this point, backend_type
             * cannot be obtained to determine if it falls in any of the above
             * cases and exec mode cannot be determined.
             */
            ALOGV("%s: EXEC_MODE_CFG_DYNAMIC: req exec mode NONE", __func__);
            if ((stdev->transit_to_adsp_on_playback &&
                    (stdev->rx_concurrency_active > 0)) ||
                (stdev->transit_to_adsp_on_battery_charging &&
                     stdev->is_charging)) {
                /* Load on ADSP */
                if (num_sessions < stdev->max_ape_sessions) {
                    if (common_sm->type == SOUND_MODEL_TYPE_KEYPHRASE) {
                        /* Keyphrase sound model */
                        if (check_phrases_users_available(v_info, num_phrases,
                            num_users, ST_EXEC_MODE_ADSP, false))
                            exec_mode = ST_EXEC_MODE_ADSP;
                    } else {
                        /* Generic sound model without keyphrases */
                        exec_mode = ST_EXEC_MODE_ADSP;
                    }
                }
            } else {
                /* Load on WDSP */
                if (num_sessions < stdev->max_wdsp_sessions) {
                    if (common_sm->type == SOUND_MODEL_TYPE_KEYPHRASE) {
                        /* Keyphrase sound model */
                        if (check_phrases_users_available(v_info, num_phrases,
                            num_users, ST_EXEC_MODE_CPE, false))
                            exec_mode = ST_EXEC_MODE_CPE;
                    } else {
                        /* Generic sound model without keyphrases */
                        exec_mode = ST_EXEC_MODE_CPE;
                    }
                }
            }
        }
    } else if (v_info->exec_mode_cfg == EXEC_MODE_CFG_ARM) {
        if (num_sessions < stdev->max_arm_sessions)
            exec_mode = ST_EXEC_MODE_ARM;
    }

    ALOGV("%s: Exit  exec_mode=%d", __func__, exec_mode);
    return exec_mode;
}

static void update_available_phrase_info
(
   st_session_t *p_ses,
   struct sound_trigger_phrase_sound_model *phrase_sm,
   bool add
)
{
    struct st_vendor_info *v_info = p_ses->vendor_uuid_info;

    if (add) {
        if (p_ses->exec_mode == ST_EXEC_MODE_CPE) {
            v_info->avail_cpe_phrases  += phrase_sm->num_phrases;
            v_info->avail_cpe_users  += p_ses->num_users;
        } else {
            v_info->avail_ape_phrases  += phrase_sm->num_phrases;
            v_info->avail_ape_users  += p_ses->num_users;
        }
    } else {
        if (p_ses->exec_mode == ST_EXEC_MODE_CPE) {
            v_info->avail_cpe_phrases  -= phrase_sm->num_phrases;
            v_info->avail_cpe_users  -= p_ses->num_users;
        } else {
            v_info->avail_ape_phrases  -= phrase_sm->num_phrases;
            v_info->avail_ape_users  -= p_ses->num_users;
        }
    }
}

static bool compare_recognition_config
(
   const struct sound_trigger_recognition_config *current_config,
   struct sound_trigger_recognition_config *new_config
)
{
    unsigned int i = 0, j = 0;

    /*
     * Sometimes if the number of user confidence levels is 0, the
     * sound_trigger_confidence_level struct will be different between the two
     * configs. So all the values must be checked instead of a memcmp of the
     * whole configs.
     */

    /*
     * Extra uint32_t is added in memcmp as opaque data config starts after
     * audio_capabilities as per SOUND_TRIGGER_DEVICE_API_VERSION_1_3
     */

    if ((current_config->capture_handle != new_config->capture_handle) ||
        (current_config->capture_device != new_config->capture_device) ||
        (current_config->capture_requested != new_config->capture_requested) ||
        (current_config->num_phrases != new_config->num_phrases) ||
        (current_config->data_size != new_config->data_size) ||
        (current_config->data_offset != new_config->data_offset) ||
        (hw_properties_extended.header.version == SOUND_TRIGGER_DEVICE_API_VERSION_1_3 &&
         memcmp((char *) current_config + current_config->data_offset,
               (char *) new_config + sizeof(struct sound_trigger_recognition_config) +
                sizeof(uint32_t), current_config->data_size)) ||
        (hw_properties_extended.header.version == SOUND_TRIGGER_DEVICE_API_VERSION_1_0 &&
         memcmp((char *) current_config + current_config->data_offset,
               (char *) new_config + new_config->data_offset,
               current_config->data_size))) {
        return false;
    } else {
        for (i = 0; i < current_config->num_phrases; i++) {
            if ((current_config->phrases[i].id !=
                 new_config->phrases[i].id) ||
                (current_config->phrases[i].recognition_modes !=
                 new_config->phrases[i].recognition_modes) ||
                (current_config->phrases[i].confidence_level !=
                 new_config->phrases[i].confidence_level) ||
                (current_config->phrases[i].num_levels !=
                 new_config->phrases[i].num_levels)) {
                return false;
            } else {
                for (j = 0; j < current_config->phrases[i].num_levels; j++) {
                    if ((current_config->phrases[i].levels[j].user_id !=
                         new_config->phrases[i].levels[j].user_id) ||
                        (current_config->phrases[i].levels[j].level !=
                         new_config->phrases[i].levels[j].level))
                        return false;
                }
            }
        }
        return true;
    }
}

static int load_audio_hal()
{
    int status = 0;
    char audio_hal_lib[100];
    void *sthal_prop_api_version;

    snprintf(audio_hal_lib, sizeof(audio_hal_lib), "%s/%s.%s.so",
             AUDIO_HAL_LIBRARY_PATH1, AUDIO_HAL_NAME_PREFIX,
             XSTR(SOUND_TRIGGER_PLATFORM));
    if (access(audio_hal_lib, R_OK)) {
        snprintf(audio_hal_lib, sizeof(audio_hal_lib), "%s/%s.%s.so",
                 AUDIO_HAL_LIBRARY_PATH2, AUDIO_HAL_NAME_PREFIX,
                 XSTR(SOUND_TRIGGER_PLATFORM));
        if (access(audio_hal_lib, R_OK)) {
            ALOGE("%s: ERROR. %s not found", __func__, audio_hal_lib);
            return -ENOENT;
        }
    }

    stdev->audio_hal_handle = dlopen(audio_hal_lib, RTLD_NOW);
    if (!stdev->audio_hal_handle) {
        ALOGE("%s: ERROR. %s", __func__, dlerror());
        return -ENODEV;
    }

    DLSYM(stdev->audio_hal_handle, stdev->audio_hal_cb, audio_hw_call_back,
          status);
    if (status)
        goto error;

    DLSYM(stdev->audio_hal_handle, sthal_prop_api_version,
          sthal_prop_api_version, status);
    if (status) {
        stdev->sthal_prop_api_version = 0;
        status  = 0; /* passthru for backward compability */
    } else {
        stdev->sthal_prop_api_version = *(int*)sthal_prop_api_version;
        if (MAJOR_VERSION(stdev->sthal_prop_api_version) !=
            MAJOR_VERSION(STHAL_PROP_API_CURRENT_VERSION)) {
            ALOGE("%s: Incompatible API versions sthal:0x%x != ahal:0x%x",
                  __func__, STHAL_PROP_API_CURRENT_VERSION,
                  stdev->sthal_prop_api_version);
            goto error;
        }
        ALOGD("%s: ahal is using proprietary API version 0x%04x", __func__,
              stdev->sthal_prop_api_version);
    }
    return status;

error:
    dlclose(stdev->audio_hal_handle);
    stdev->audio_hal_handle = NULL;
    return status;
}

#ifndef USE_KEEP_ALIVE
#define run_keep_alive_session(stdev, st_ses, event) (0)
#else
static void run_keep_alive_session(struct sound_trigger_device *stdev,
                                   st_session_t *st_ses, int event)
{
    struct sound_trigger_event_info event_info;

    ALOGV("%s: keep alive event %d", __func__, event);
    event_info.st_ses.p_ses = NULL;
    if ((ST_EXEC_MODE_ARM == st_ses->exec_mode) &&
        !st_ses->vendor_uuid_info->split_ec_ref_data)
        stdev->audio_hal_cb(event, &event_info);

}
#endif /*USE_KEEP_ALIVE*/

static int allocate_arm_second_stage_session(struct st_arm_second_stage **st_sec_stage,
                                             unsigned int sm_size)
{
    int status = 0;

    *st_sec_stage = calloc(1, sizeof(struct st_arm_second_stage));
    if (!*st_sec_stage) {
        ALOGE("%s: failed to allocate struct st_arm_second_stage", __func__);
        status = -ENOMEM;
        goto exit;
    }
    (*st_sec_stage)->ss_info = calloc(1, sizeof(struct st_second_stage_info));
    if (!(*st_sec_stage)->ss_info) {
        ALOGE("%s: failed to allocate struct st_second_stage_info", __func__);
        status = -ENOMEM;
        goto exit;
    }
    (*st_sec_stage)->ss_session = calloc(1, sizeof(struct st_arm_ss_session));
    if (!(*st_sec_stage)->ss_session) {
        ALOGE("%s: failed to allocate struct st_arm_ss_session", __func__);
        status = -ENOMEM;
        goto exit;
    }
    (*st_sec_stage)->ss_session->sound_model = calloc(sm_size, sizeof(char));
    if (!(*st_sec_stage)->ss_session->sound_model) {
        ALOGE("%s: failed to allocate second stage sound model", __func__);
        status = -ENOMEM;
        goto exit;
    }

exit:
    return status;
}

static void deallocate_arm_second_stage_session(
   struct st_arm_second_stage *st_sec_stage)
{
    if (st_sec_stage) {
        if (st_sec_stage->ss_info) {
            free(st_sec_stage->ss_info);
            st_sec_stage->ss_info = NULL;
        }
        if (st_sec_stage->ss_session) {
            st_sec_stage->ss_session->st_ses = NULL;
            if (st_sec_stage->ss_session->sound_model) {
                free(st_sec_stage->ss_session->sound_model);
                st_sec_stage->ss_session->sound_model = NULL;
            }
            free(st_sec_stage->ss_session);
            st_sec_stage->ss_session = NULL;
        }
        free(st_sec_stage);
        st_sec_stage = NULL;
    }
}

static int allocate_lsm_ss_config(st_lsm_ss_config_t **ss_cfg, size_t sm_size)
{
    st_lsm_ss_config_t *cfg;

    cfg = calloc(1, sizeof(st_lsm_ss_config_t));
    if (!cfg) {
        ALOGE("%s: failed to allocate lsm ss config", __func__);
        return -ENOMEM;
    }
    cfg->sm_data = calloc(sm_size, sizeof(char));
    if (!cfg->sm_data) {
        ALOGE("%s: failed to allocate sound model lsm ss config", __func__);
        free(cfg);
        return -ENOMEM;
    }
    *ss_cfg = cfg;
    return 0;
}

static void deallocate_lsm_ss_config(st_lsm_ss_config_t *ss_cfg)
{
    if (ss_cfg) {
        free(ss_cfg->sm_data);
        free(ss_cfg);
    }
}

/*
 * This function takes the sound model id from each SML_BigSoundModelTypeV3 in
 * the sound_trigger_sound_model payload, and looks for a match in the platform
 * list derived from the platform xml file. If there is a match, allocate the
 * structures needed to support a second stage session.
 */
static int check_and_configure_second_stage_models
(
    st_session_t *st_ses,
    uint8_t *sm_payload,
    uint32_t num_models,
    uint32_t recognition_mode
)
{
    int ret = 0;
    struct st_ss_usecase ss_usecase;
    struct st_arm_second_stage *st_sec_stage = NULL;
    SML_BigSoundModelTypeV3 *big_sm;
    uint32_t i;
    uint8_t *sound_model;

    for (i = 0; i < num_models; i++) {
        big_sm = (SML_BigSoundModelTypeV3 *)(sm_payload + sizeof(SML_GlobalHeaderType) +
            sizeof(SML_HeaderTypeV3) + (i * sizeof(SML_BigSoundModelTypeV3)));

        if (big_sm->type != ST_SM_ID_SVA_GMM) {
            if (big_sm->type == SML_ID_SVA_S_STAGE_UBM || (big_sm->type == ST_SM_ID_SVA_VOP &&
                !(recognition_mode & RECOGNITION_MODE_USER_IDENTIFICATION)))
                continue;

            ss_usecase = platform_get_ss_usecase(st_ses->vendor_uuid_info, big_sm->type);
            if (ss_usecase.type == ST_SS_USECASE_TYPE_ARM) {
                ret = allocate_arm_second_stage_session(&st_sec_stage, big_sm->size);
                if (ret || (st_sec_stage == NULL)) {
                    ALOGE("%s: failed to allocate arm second stage session", __func__);
                    goto exit;
                }

                st_sec_stage->ss_session->sm_size = big_sm->size;
                sound_model = (uint8_t *)(sm_payload + sizeof(SML_GlobalHeaderType) +
                    sizeof(SML_HeaderTypeV3) + (num_models * sizeof(SML_BigSoundModelTypeV3)) +
                    big_sm->offset);

                memcpy(st_sec_stage->ss_session->sound_model, sound_model, big_sm->size);
                memcpy((char *)st_sec_stage->ss_info, (char *)&ss_usecase.arm->common_params,
                    sizeof(struct st_second_stage_info));
                st_sec_stage->stdev = st_ses->stdev;
                list_add_tail(&st_ses->second_stage_list, &st_sec_stage->list_node);
                ALOGD("%s: Added second stage session of type %d", __func__,
                    st_sec_stage->ss_info->sm_detection_type);
            } else if (ss_usecase.type == ST_SS_USECASE_TYPE_LSM) {
                st_lsm_ss_config_t *ss_cfg = NULL;

                if (!st_hw_check_ses_ss_usecase_allowed(st_ses)) {
                    ALOGE("%s: cannot add requested lsm ss usecase", __func__);
                    ret = -EBUSY;
                    goto exit;
                }

                ret = allocate_lsm_ss_config(&ss_cfg, big_sm->size);
                if (ret) {
                    ALOGE("%s: failed to allocate lsm ss config", __func__);
                    goto exit;
                }

                ss_cfg->sm_size = big_sm->size;
                sound_model = (uint8_t *)(sm_payload + sizeof(SML_GlobalHeaderType) +
                    sizeof(SML_HeaderTypeV3) + (num_models * sizeof(SML_BigSoundModelTypeV3)) +
                    big_sm->offset);
                memcpy(ss_cfg->sm_data, sound_model, big_sm->size);

                ss_cfg->params = ss_usecase.lsm;
                ss_cfg->ss_info = &ss_usecase.lsm->common_params;
                list_add_tail(&st_ses->hw_proxy_ses->hw_ses_adsp->lsm_ss_cfg_list,
                    &ss_cfg->list_node);
                ALOGD("%s: Added second stage lsm usecase with sm id %d", __func__, big_sm->type);
            } else if (ss_usecase.type == ST_SS_USECASE_TYPE_NONE) {
                ALOGE("%s: No matching usecase in sound trigger platform for sm_id %d",
                    __func__, big_sm->type);
                ret = -EINVAL;
                goto exit;
            }
        }
    }

    return 0;

exit:
    deallocate_arm_second_stage_session(st_sec_stage);
    return ret;
}

/*
 * This function finds the first stage sound model raw data size and offset, and sets
 * the sound_trigger_sound_model payload size and offset to these values.
 */
static int get_first_stage_model(struct sound_trigger_sound_model **common_sm,
                         uint8_t *sm_payload, uint32_t num_models,
                         st_module_type_t *sm_version)
{
    SML_BigSoundModelTypeV3 *big_sm = NULL;
    uint32_t i = 0;
    int status = 0;

    for (i = 0; i < num_models; i++) {
        big_sm = (SML_BigSoundModelTypeV3 *)(sm_payload + sizeof(SML_GlobalHeaderType) +
            sizeof(SML_HeaderTypeV3) + (i * sizeof(SML_BigSoundModelTypeV3)));
        if (big_sm->type == ST_SM_ID_SVA_GMM) {
            if (big_sm->versionMajor == ST_MODULE_TYPE_PDK5)
                *sm_version = ST_MODULE_TYPE_PDK5;
            else
                *sm_version = ST_MODULE_TYPE_GMM;
            (*common_sm)->data_size = big_sm->size;
            (*common_sm)->data_offset += sizeof(SML_GlobalHeaderType) + sizeof(SML_HeaderTypeV3) +
                (num_models * sizeof(SML_BigSoundModelTypeV3)) + big_sm->offset;
            break;
        }
    }
    if (!(*common_sm)) {
        ALOGE("%s: common_sm was not initialized, exiting", __func__);
        status = -EINVAL;
    }
    return status;
}

#ifdef ST_SUPPORT_GET_MODEL_STATE
static int stdev_get_model_state(const struct sound_trigger_hw_device *dev,
    sound_model_handle_t handle)
{
    int status = 0;
    st_session_t* st_ses = NULL;
    struct sound_trigger_device *stdev = (struct sound_trigger_device *)dev;

    ALOGD("%s:[%d] Enter", __func__, handle);

    if (!stdev) {
        ALOGE("%s: sound_trigger_device is NULL, exiting", __func__);
        return -ENODEV;
    }

    pthread_mutex_lock(&stdev->lock);
    st_ses = get_sound_trigger_session(stdev, handle);
    if (!st_ses) {
        ALOGE("%s: Error - no sound trigger session with handle %d",
            __func__, handle);
        status = -ENOSYS;
        goto err_exit;
    }

    status = st_session_request_detection(st_ses);

err_exit:
    pthread_mutex_unlock(&stdev->lock);
    ALOGD("%s: Exit, status %d", __func__, status);
    return status;
}
#endif

static int stdev_load_sound_model(const struct sound_trigger_hw_device *dev,
                                  struct sound_trigger_sound_model *sound_model,
                                  sound_model_callback_t callback __unused,
                                  void *cookie __unused,
                                  sound_model_handle_t *handle)
{
    int status = 0;
    st_exec_mode_t exec_mode;
    st_session_t *st_session = NULL;
    struct sound_trigger_phrase_sound_model *phrase_sm = NULL;
    struct sound_trigger_sound_model *common_sm = NULL;
    unsigned int sm_size = 0;
    struct sound_trigger_device *stdev = (struct sound_trigger_device *)dev;
    uint8_t *sm_payload;
    SML_GlobalHeaderType *global_hdr;
    SML_HeaderTypeV3 *hdr_v3;
    uint32_t num_models = 0, sml_version = SML_MODEL_V2;
    st_module_type_t sm_version = ST_MODULE_TYPE_GMM;
    struct listnode *node = NULL, *tmp_node = NULL;
    struct st_arm_second_stage *st_sec_stage = NULL;

    ALOGD("%s", __func__);
    ATRACE_BEGIN("sthal: stdev_load_sound_model");

    pthread_mutex_lock(&stdev->lock);

    if (handle == NULL || sound_model == NULL) {
        status = -EINVAL;
        goto exit;
    }

    /*
     * For LPMA feature, client just passes known vendor_uuid to start the
     * LPMA usecase. This is a hacky way of reusing existing HAL interface
     * to start/stop LPMA non-VA usecase from client.
     */
    if (!memcmp(&sound_model->vendor_uuid,
                &lpma_uuid, sizeof(sound_trigger_uuid_t))) {
        if (stdev->lpma_handle == -1) {
            status = sthw_extn_lpma_notify_event(LPMA_EVENT_START);
            *handle = (!status ? android_atomic_inc(&stdev->session_id): -1);
            stdev->lpma_handle = *handle;
        } else {
            ALOGD("%s: lpma is already started", __func__);
            *handle = stdev->lpma_handle;
        }
        pthread_mutex_unlock(&stdev->lock);
        ATRACE_END();
        ALOGD("%s: lpma exit status %d", __func__, status);
        return status;
    }

    /*
     * for swmad case dont load sm and return failure to client
     */
    if (!stdev->session_allowed && stdev->sw_mad) {
        ALOGW("%s: session prevented by concurrency", __func__);
        status = -ENODEV;
        goto exit;
    }

    if (sound_model->type == SOUND_MODEL_TYPE_KEYPHRASE) {
        phrase_sm = (struct sound_trigger_phrase_sound_model *)sound_model;
        if ((phrase_sm->common.data_size == 0) ||
            (phrase_sm->common.data_offset < sizeof(*phrase_sm)) ||
            (phrase_sm->common.type != SOUND_MODEL_TYPE_KEYPHRASE) ||
            (phrase_sm->num_phrases == 0)) {
            ALOGE("%s: Invalid phrase sound model params data size=%d, data offset=%d, "
                  "type=%d phrases=%d", __func__, phrase_sm->common.data_size,
                  phrase_sm->common.data_offset, phrase_sm->common.type,
                  phrase_sm->num_phrases);
            status = -EINVAL;
            goto exit;
        }
        common_sm = &phrase_sm->common;
        sm_payload = (uint8_t *)common_sm + common_sm->data_offset;
        global_hdr = (SML_GlobalHeaderType *)sm_payload;
        if (global_hdr->magicNumber == SML_GLOBAL_HEADER_MAGIC_NUMBER) {
            sml_version = SML_MODEL_V3;
            hdr_v3 = (SML_HeaderTypeV3 *)(sm_payload + sizeof(SML_GlobalHeaderType));
            num_models = hdr_v3->numModels;
            status = get_first_stage_model(&common_sm, sm_payload, num_models, &sm_version);
            if (status) {
                ALOGE("%s: Failed to set the first stage sound modle offset and size",
                    __func__);
                goto exit;
            }
        }
        sm_size = sizeof(*phrase_sm) + phrase_sm->common.data_size;
    } else if (sound_model->type == SOUND_MODEL_TYPE_GENERIC) {
        if (!sound_model->data_size ||
            (sound_model->data_offset < sizeof(*common_sm))) {
            ALOGE("%s: Invalid Generic sound model params data size=%d, data offset=%d",
                  __func__, sound_model->data_size, sound_model->data_offset);
            status = -EINVAL;
            goto exit;
        }
        common_sm = sound_model;
        sm_size = sizeof(*common_sm) + common_sm->data_size;
        sm_payload = (uint8_t *)common_sm + common_sm->data_offset;
    } else {
        ALOGE("%s: Unknown sound model type %d", __func__, sound_model->type);
        status = -EINVAL;
        goto exit;
    }

    ALOGV("%s: sm_size=%d data_size=%d", __func__, sm_size, common_sm->data_size);
    st_session = calloc(1, sizeof(st_session_t));
    if (!st_session) {
        status = -ENOMEM;
        goto exit;
    }
    list_init(&st_session->second_stage_list);

    st_session->f_stage_version = sm_version;

    /* CPE takes time to become online, so parse for the pcm devices
       here instead during boot time */
    if (!CHECK_BIT(stdev->hw_type,
            ST_DEVICE_HW_APE|ST_DEVICE_HW_CPE|ST_DEVICE_HW_ARM)) {
        status = platform_stdev_get_hw_type(stdev->platform);
        if (status)
            goto exit;
    }

    st_session->vendor_uuid_info = platform_stdev_get_vendor_info(
                                      stdev->platform,
                                      &common_sm->vendor_uuid);

    if (!st_session->vendor_uuid_info) {
        ALOGE("%s: no matching vendor uuid found", __func__);
        status = -EINVAL;
        goto exit;
    }

    exec_mode = get_session_exec_mode(st_session, common_sm);
    if (exec_mode == ST_EXEC_MODE_NONE) {
        status = -EINVAL;
        goto exit;
    }

    *handle = android_atomic_inc(&stdev->session_id);

    ALOGD("%s:[%d] calling st_session_init", __func__, *handle);
    status = st_session_init(st_session, stdev, exec_mode, *handle);
    if (status) {
        ALOGE("%s: failed to initialize st_session with error %d", __func__,
              status);
        goto exit_1;
    }

    ALOGD("%s: second state detection %s",__func__,
             st_session->vendor_uuid_info->second_stage_supported ? "supported" : "not supported");
    /*
     * Parse second stage sound models and populate the second stage list for
     * this session.
     */
    if (sml_version == SML_MODEL_V3 && st_session->vendor_uuid_info->second_stage_supported) {
        status = check_and_configure_second_stage_models(st_session, sm_payload,
            num_models, phrase_sm->phrases[0].recognition_mode);
        if (status) {
            ALOGE("%s: Failed to set the second stage list", __func__);
            goto exit_2;
        }
    }

    if (!list_empty(&st_session->second_stage_list)) {
        ALOGD("%s: calling st_session_ss_init ", __func__);
        status = st_session_ss_init(st_session);
        if (status) {
            ALOGE("%s: failed to initialize st_session second stage,"
                  "error %d", __func__, status);
            goto exit_2;
        }
    }

    /*
     * Store the sound model information for handling SSR
     * and interaction with smlib
     */
    st_session->phrase_sm = calloc(1, sm_size);
    if (!st_session->phrase_sm) {
        status = -ENOMEM;
        goto exit_3;
    }

    if (sound_model->type == SOUND_MODEL_TYPE_KEYPHRASE) {
        memcpy(st_session->phrase_sm, (char *)phrase_sm, sizeof(*phrase_sm));
        st_session->phrase_sm->common.data_offset = sizeof(*phrase_sm);
        memcpy((char *)st_session->phrase_sm + sizeof(*phrase_sm),
               (char *)phrase_sm + phrase_sm->common.data_offset,
               phrase_sm->common.data_size);
        /* TODO: SVA doesn't support per keyword recognition mode.
         * So use the first phrase recognition mode. App is supposed
         * to set the proper recognition mode in the first phrase
         */
        st_session->recognition_mode = phrase_sm->phrases[0].recognition_mode;
        ALOGD("%s: sm magic number 0x%x rm %d", __func__,
              ((int *)((char *)st_session->phrase_sm +
                       phrase_sm->common.data_offset))[0],
              phrase_sm->phrases[0].recognition_mode);
    } else {
        st_session->recognition_mode = RECOGNITION_MODE_VOICE_TRIGGER;
        memcpy(st_session->phrase_sm, (char *)common_sm, sizeof(*common_sm));
        memcpy((char *)st_session->phrase_sm + common_sm->data_offset,
               (char *)common_sm + common_sm->data_offset,
               common_sm->data_size);
        ALOGD("%s: sm magic number 0x%x", __func__,
              ((int *)((char *)st_session->phrase_sm +
                       common_sm->data_offset))[0]);
    }

    st_session->sm_type = sound_model->type;
    st_hw_check_and_update_lpi(stdev, NULL);
    st_hw_check_and_set_lpi_mode(st_session);

    status = st_session_load_sm(st_session);
    if (status) {
        goto exit_3;
    }

    if (!stdev->session_allowed) {
        status = st_session_pause(st_session);
        if (status) {
            st_session_unload_sm(st_session);
            goto exit_3;
        }
    }

    /* Keyphrase, user information is valid only for keyphrase sound models */
    if ((common_sm->type == SOUND_MODEL_TYPE_KEYPHRASE) && (phrase_sm != NULL))
        update_available_phrase_info(st_session, phrase_sm, false);

    /* Add the session to the list of registered sound models list */
    list_add_tail(&stdev->sound_model_list, &st_session->list_node);

    pthread_mutex_unlock(&stdev->lock);

    ATRACE_END();

    run_keep_alive_session(stdev, st_session, ST_EVENT_START_KEEP_ALIVE);
    ALOGD("%s: success, sound_model_handle %d", __func__, st_session->sm_handle);
    return 0;

exit_3:
    if (st_session->phrase_sm != NULL)
        free(st_session->phrase_sm);
    if (!list_empty(&st_session->second_stage_list))
        st_session_ss_deinit(st_session);

exit_2:
    st_session_deinit(st_session);

exit_1:
    android_atomic_dec(&stdev->session_id);

exit:
    if (st_session != NULL) {
        list_for_each_safe(node, tmp_node, &st_session->second_stage_list) {
            st_sec_stage = node_to_item(node, st_arm_second_stage_t, list_node);
            list_remove(&st_sec_stage->list_node);
            deallocate_arm_second_stage_session(st_sec_stage);
        }
        if (st_session->hw_proxy_ses &&
            st_session->hw_proxy_ses->hw_ses_adsp) {
            list_for_each_safe(node, tmp_node,
                &st_session->hw_proxy_ses->hw_ses_adsp->lsm_ss_cfg_list) {
                st_lsm_ss_config_t *cfg =
                node_to_item(node, st_lsm_ss_config_t, list_node);
                list_remove(&cfg->list_node);
                deallocate_lsm_ss_config(cfg);
            }
        }
        free(st_session);
        st_session = NULL;
    }
    if (handle != NULL)
        *handle = -1;
    pthread_mutex_unlock(&stdev->lock);
    ATRACE_END();
    return status;
}

/* called with stdev lock held */
static int stdev_reconfig_backend_on_stop(st_session_t *stopped_ses)
{
    /*
     * Of the remaining sessions, pick the session with the
     * best ch_count, rate, format and reconfigure backend according to it.
     * Examples
     *    1) Assume two sessions are active. S1 is using mono and S2 is using stereo.
     *       As S2 is using stereo, backend will be configured as stereo.
     *       If S1 stops, maintain backend as stereo.
     *       If S2 stops, change backend to mono
     *    2) Assume single session S2 (stereo)
     *       If S2 stops, reset backend to allow a future session (S1) to
     *       to optimally set the backend at mono.
     */
    st_session_t *best_ses = NULL;
    st_session_t *ses = NULL;
    struct listnode *ses_node = NULL;
    int ses_channel_count = 0;
    int stopped_ses_channel_count = 0;
    int best_channel_count = 0;
    unsigned int stopped_ses_vad_preroll = 0;
    unsigned int best_vad_preroll = 0, preroll = 0;
    bool stopped_ses_lpi_mode = false, is_stopped = false;

    if (stopped_ses->exec_mode != ST_EXEC_MODE_ADSP &&
        stopped_ses->exec_mode != ST_EXEC_MODE_ARM)
        return 0;

    is_stopped = (st_session_is_detected(stopped_ses) == false) &&
                 (st_session_is_active(stopped_ses) == false) &&
                 (st_session_is_buffering(stopped_ses) == false);

    if (!is_stopped || is_any_session_buffering()) {
        ALOGW("defer backend reconfig as session not stopped or buffering");
        return 0;
    }

    struct st_vendor_info *stopped_v_info = stopped_ses->vendor_uuid_info;
    ALOGV("%s:[%d] v_info %p", __func__, stopped_ses->sm_handle, stopped_v_info);

    stopped_ses_channel_count =
        platform_stdev_get_backend_channel_count(stdev->platform,
                                                 stopped_v_info);

    if ((stopped_ses->exec_mode == ST_EXEC_MODE_ADSP) &&
        stopped_ses->hw_proxy_ses->hw_ses_adsp) {
        stopped_ses_lpi_mode = stopped_ses->hw_proxy_ses->hw_ses_adsp->lpi_enable;
        stopped_ses_vad_preroll = st_session_get_preroll(stopped_ses);
    }

    list_for_each(ses_node, &stdev->sound_model_list) {
        ses = node_to_item(ses_node, st_session_t, list_node);
        if (ses->exec_mode != ST_EXEC_MODE_ADSP &&
            ses->exec_mode != ST_EXEC_MODE_ARM)
            continue;
        if (ses == stopped_ses) {
            ALOGV("ses == stopped_ses, ignore");
            continue;
        }

        is_stopped = (st_session_is_detected(ses) == false) &&
                      (st_session_is_active(ses) == false) &&
                      (st_session_is_buffering(ses) == false);
        if (is_stopped) {
            ALOGV("%s:[%d] is stopped, ignore", __func__, ses->sm_handle);
            continue;
        }

        ses_channel_count =
            platform_stdev_get_backend_channel_count(stdev->platform,
              ses->vendor_uuid_info);
        ALOGV("%s:[%d] check ses_v_info %p", __func__, ses->sm_handle,
            ses->vendor_uuid_info);

        if (ses->exec_mode == ST_EXEC_MODE_ADSP) {
            preroll = st_session_get_preroll(ses);
            if (preroll > best_vad_preroll)
                best_vad_preroll = preroll;
        }

        if ((best_ses == NULL) || (ses_channel_count > best_channel_count)) {
            best_ses = ses;
            best_channel_count = ses_channel_count;
        }
    }

    st_hw_check_and_update_lpi(stdev, NULL);
    stdev->vad_enable = st_hw_check_vad_support(stdev, best_ses,
                                                stdev->lpi_enable);

    /* skip reconfig/reset if any other session still active with best config */
    if ((best_ses != NULL) &&
        (stopped_ses_channel_count <= best_channel_count) &&
        (stopped_ses_lpi_mode == stdev->lpi_enable) &&
        (stopped_ses_vad_preroll <= best_vad_preroll)) {
        ALOGV("%s: stdev %p skipped reconfig", __func__, stdev);
        return 0;
    }

    if (best_ses) {
        platform_stdev_set_codec_backend_cfg(stdev->platform,
                                             best_ses->vendor_uuid_info,
                                             stdev->lpi_enable,
                                             stdev->vad_enable,
                                             best_vad_preroll);
        ALOGI("%s:[%d] force changed backend to %d", __func__,
              best_ses->sm_handle, best_channel_count);
        stop_other_sessions(stdev, stopped_ses);
        start_other_sessions(stdev, stopped_ses);
    } else {
        ALOGI("%s: no session remains, reset to default", __func__);
        platform_stdev_reset_backend_cfg(stdev->platform);
    }

    return 0;
}


/* to be called with no locks held */
static void stdev_session_event_cb(sound_model_handle_t handle,
                                   st_session_event_id_t event)
{
    pthread_mutex_lock(&stdev->lock);
    st_session_t* st_ses = get_sound_trigger_session(stdev, handle);

    if (!st_ses)
        goto exit;

    ALOGV("%s:[%d] event %d", __func__, handle, event);
    switch (event) {
    case ST_SES_EV_DEFERRED_STOP:
        if (st_ses->pending_stop)
            stop_recognition_l(st_ses);
        break;
    default:
        break;
    }
exit:
    pthread_mutex_unlock(&stdev->lock);
}

static int stdev_unload_sound_model(const struct sound_trigger_hw_device *dev,
                                    sound_model_handle_t handle)
{
    struct sound_trigger_device *stdev = (struct sound_trigger_device *)dev;
    st_session_t *st_session = NULL;
    int status = 0, ret = 0;
    struct listnode *node = NULL, *tmp_node = NULL;
    struct st_arm_second_stage *st_sec_stage = NULL;

    ALOGD("%s:[%d] Enter", __func__, handle);
    ATRACE_BEGIN("sthal: stdev_unload_sound_model");

    pthread_mutex_lock(&stdev->lock);
    if (handle == stdev->lpma_handle) {
        status = sthw_extn_lpma_notify_event(LPMA_EVENT_STOP);
        stdev->lpma_handle = -1;
        pthread_mutex_unlock(&stdev->lock);
        ATRACE_END();
        ALOGD("%s: lpma exit status %d", __func__, status);
        return status;
    }

    st_session = get_sound_trigger_session(stdev, handle);
    if (!st_session) {
        ALOGE("%s: Could not find sound model %d", __func__, handle);
        ret = -EINVAL;
        goto exit;
    }

    ALOGD("%s:[%d] fs detections: %d, ss detections: %d, ss rejections: %d",
        __func__, handle, st_session->fs_det_count, st_session->ss_det_count,
        st_session->ss_rej_count);

    if (st_session->callback) {
        status = stop_recognition_l(st_session);
        if (status) {
            ALOGE("%s:[%d] Failed to stop recognition, status %d", __func__,
                handle, status);
            ret = status;
        }
    }

    status = st_session_unload_sm(st_session);
    if (status) {
        ALOGE("%s:[%d] Failed to unload sound model, status %d", __func__,
            handle, status);
        ret = status;
    }

    list_remove(&st_session->list_node);

    if (st_session->sm_type == SOUND_MODEL_TYPE_KEYPHRASE)
        update_available_phrase_info(st_session, st_session->phrase_sm, true);

    if (!get_num_sessions())
        stdev->exec_mode = ST_EXEC_MODE_NONE;

    pthread_mutex_lock(&st_session->lock);
    free(st_session->phrase_sm);
    pthread_mutex_unlock(&st_session->lock);

    run_keep_alive_session(stdev, st_session, ST_EVENT_STOP_KEEP_ALIVE);
    if (!list_empty(&st_session->second_stage_list)) {
        st_session_ss_deinit(st_session);
        list_for_each_safe(node, tmp_node, &st_session->second_stage_list) {
            st_sec_stage = node_to_item(node, st_arm_second_stage_t, list_node);
            list_remove(&st_sec_stage->list_node);
            deallocate_arm_second_stage_session(st_sec_stage);
        }
    }
    if (st_session && st_session->hw_proxy_ses->hw_ses_adsp) {
        list_for_each_safe(node, tmp_node,
            &st_session->hw_proxy_ses->hw_ses_adsp->lsm_ss_cfg_list) {
            st_lsm_ss_config_t *cfg =
                node_to_item(node, st_lsm_ss_config_t, list_node);
            list_remove(&cfg->list_node);
            deallocate_lsm_ss_config(cfg);
        }
    }
    st_session_deinit(st_session);

    free(st_session);

exit:
    pthread_mutex_unlock(&stdev->lock);
    ATRACE_END();
    ALOGD("%s: Exit status %d", __func__, ret);
    return ret;
}

static int stdev_start_recognition
(
   const struct sound_trigger_hw_device *dev,
   sound_model_handle_t sound_model_handle,
   const struct sound_trigger_recognition_config *config,
   recognition_callback_t callback,
   void *cookie
)
{
    struct sound_trigger_device *stdev = (struct sound_trigger_device *)dev;
    st_session_t *st_session = NULL;
    int status = 0;
    bool config_updated = false;
    bool backend_cfg_change = false;

    ALOGD("%s:[%d] Enter", __func__, sound_model_handle);
    ATRACE_BEGIN("sthal: stdev_start_recognition");

    pthread_mutex_lock(&stdev->lock);

    if (!callback || !config) {
        ALOGE("%s: ERROR. NULL params", __func__);
        status = -EINVAL;
        goto exit;
    }

    st_session = get_sound_trigger_session(stdev, sound_model_handle);
    if (!st_session) {
        ALOGE("%s: ERROR. Could not find session for sound model %d", __func__,
           sound_model_handle);
        status = -EINVAL;
        goto exit;
    }

    ALOGV("%s:[%d] About to take session lock", __func__, sound_model_handle);
    pthread_mutex_lock(&st_session->lock);
    if (!st_session->rc_config ||
        !compare_recognition_config(config, st_session->rc_config)) {
        config_updated = true;

        ALOGV("%s:[%d] received new params ", __func__, st_session->sm_handle);

        /*
         * Store the recogntion configuration for sending opaque data
         * and for SSR, passing to sounmodel wrapper library.
         */
        if (st_session->rc_config)
            free(st_session->rc_config);

        /*
         * 2nd stage sessions require SVA 3.0 opaque data. This check prevents
         * the session from being active with the wrong settings.
         */
        if ((config->data_size <= CUSTOM_CONFIG_OPAQUE_DATA_SIZE) &&
            st_session->vendor_uuid_info->is_qcva_uuid &&
            !list_empty(&st_session->second_stage_list)) {
            ALOGE("%s: SVA 3.0 rc_config opaque data required, exiting",
                  __func__);
            status = -EINVAL;
            goto cleanup;
        }

        st_session->rc_config = calloc(1, sizeof(*config) + config->data_size);
        if (!st_session->rc_config) {
            ALOGE("%s: No memory for rc_config", __func__);
            status = -ENOMEM;
            goto cleanup;
        }

        memcpy(st_session->rc_config, (char *)config, sizeof(*config));

        /*
         * SOUND_TRIGGER_DEVICE_API_VERSION_1_3 version introduced new strucutre
         * sound_trigger_recognition_config_extended_1_3 containing header and base,
         * so the data_offset for opaque data is relative to this new structure,
         * leading to extra 12 bytes (8 bytes for header and 4 bytes for audio_capabilities)
         * w.r.t recoginition config structure. So the extra bytes need to be subtracted
         * from the data_offset passed considering new strucutre. Opaque data starts after
         * audio_capabilities variable in sound_trigger_recognition_config_extended_1_3
         */
        if (hw_properties_extended.header.version == SOUND_TRIGGER_DEVICE_API_VERSION_1_3) {
            st_session->rc_config->data_offset -= (sizeof(struct sound_trigger_recognition_config_header) +
                                                   sizeof(uint32_t));

            memcpy((char *)st_session->rc_config + st_session->rc_config->data_offset,
                    (char *)config + config->data_offset -
                    sizeof(struct sound_trigger_recognition_config_header),
                    config->data_size);
        } else {
            memcpy((char *)st_session->rc_config + st_session->rc_config->data_offset,
                   (char *)config + config->data_offset, config->data_size);
        }

        ALOGVV("%s: num_phrases=%d, id=%d", __func__,
               st_session->rc_config->num_phrases,
               st_session->rc_config->phrases[0].id);
        st_session->callback = callback;
        st_session->cookie = cookie;
        /* capture_handle will be shared with AHAL for reading LAB data */
        st_session->capture_handle = config->capture_handle;
        st_session->capture_requested = config->capture_requested;

       /*
        * Must be called before lpi decision with updated config:
        * preroll, client requested mode etc..
        */
        status = st_session_update_recongition_config(st_session);
        if (status) {
            ALOGE("%s: ERROR. updating rc_config, returned status %d",
                  __func__, status);
            goto cleanup;
        }
    }

    if (ST_EXEC_MODE_ADSP == st_session->exec_mode ||
        ST_EXEC_MODE_ARM == st_session->exec_mode) {
        st_hw_check_and_update_lpi(stdev, st_session);
        stdev->vad_enable = st_hw_check_vad_support(stdev, st_session,
                                                    stdev->lpi_enable);
        int vad_preroll = st_session_get_preroll(st_session);

        status = platform_stdev_check_and_set_codec_backend_cfg(stdev->platform,
                             st_session->vendor_uuid_info, &backend_cfg_change,
                             stdev->lpi_enable, stdev->vad_enable, vad_preroll);
        if (status) {
            ALOGE("%s: ERROR. codec backend config update failed", __func__);
            goto cleanup;
        }

        if (backend_cfg_change) {
           /*
            * If backend config change because of this session, stop and start
            * existing sessions.
            * This will ensure existing sessions are routed with same updated
            * codec backend configuration.
            * set config_updated to true so that current session is also stopped
            * and started to reflect configuration update.
            */
            ALOGV("%s: backend config change, stop existing sessions", __func__);
            stop_other_sessions(stdev, st_session);
            config_updated = true;
        }
    }

    /*
     * Check if there is any change in config, if not issue restart event
     * to state machine
     */
    if (config_updated)
        status = st_session_start(st_session);
    else
        status = st_session_restart(st_session);

    if (status) {
        /*
         * still return success to sound trigger service, as session
         * can be resumed internally due to SSR or PDR
         */
        status = 0;
        ALOGE("%s: failed to (re)start session", __func__);
    }

    if (backend_cfg_change) {
        ALOGV("%s: backend config change, start existing sessions", __func__);
        start_other_sessions(stdev, st_session);
    }

    /* Switch session to high performance/low power mode if requested by APP */
    if ((ST_EXEC_MODE_CPE == st_session->exec_mode) &&
        (ST_DET_HIGH_PERF_MODE == st_session->client_req_det_mode))
        check_and_transit_cpe_ses_to_ape(st_session);
    else if ((ST_EXEC_MODE_ADSP == st_session->exec_mode) &&
        (ST_DET_LOW_POWER_MODE == st_session->client_req_det_mode))
        check_and_transit_ape_ses_to_cpe(st_session);

cleanup:
    pthread_mutex_unlock(&st_session->lock);

exit:
    pthread_mutex_unlock(&stdev->lock);
    ATRACE_END();
    ALOGD("%s:[%d] Exit", __func__, sound_model_handle);
    return status;
}

static int stdev_start_recognition_extended
(
    const struct sound_trigger_hw_device *dev,
    sound_model_handle_t sound_model_handle,
    const struct sound_trigger_recognition_config_header *config,
    recognition_callback_t callback,
    void *cookie
)
{
    return stdev_start_recognition(dev, sound_model_handle,
           &((struct sound_trigger_recognition_config_extended_1_3 *)config)->base,
           callback, cookie);

}

static int stdev_stop_recognition(const struct sound_trigger_hw_device *dev,
                                 sound_model_handle_t sound_model_handle)
{
    struct sound_trigger_device *stdev = (struct sound_trigger_device *)dev;
    struct st_session *st_session = NULL;
    int status = 0;

    ALOGD("%s:[%d] Enter", __func__, sound_model_handle);
    ATRACE_BEGIN("sthal: stdev_stop_recognition");

    pthread_mutex_lock(&stdev->lock);

    st_session = get_sound_trigger_session(stdev, sound_model_handle);
    if (st_session == NULL) {
        ATRACE_END();
        ALOGE("%s: Could not find sound model %d", __func__, sound_model_handle);
        status = -EINVAL;
        pthread_mutex_unlock(&stdev->lock);
        return status;
    }

    /* If ftrt processing loop in progress, indicate to exit
       before acquiring the lock here */
    status = stop_recognition_l(st_session);

    pthread_mutex_unlock(&stdev->lock);
    ATRACE_END();
    ALOGD("%s:[%d] Exit status %d", __func__, sound_model_handle, status);
    return status;
}

static int stdev_close(hw_device_t *device)
{
    struct sound_trigger_device *st_device =
        (struct sound_trigger_device *)device;
    st_session_t *st_session = NULL;
    struct listnode *node = NULL, *tmp_node = NULL;
    int status = 0;

    ALOGD("%s: count=%d", __func__, stdev_ref_cnt);
    ATRACE_BEGIN("sthal: stdev_close");

    pthread_mutex_lock(&stdev_init_lock);
    if (!st_device || (--stdev_ref_cnt != 0)) {
        goto exit;
    }

    pthread_mutex_lock(&st_device->lock);
    sthw_extn_lpma_deinit();
    platform_stdev_deinit(st_device->platform);
    free(st_device->arm_pcm_use_cases);
    free(st_device->ape_pcm_use_cases);
    free(st_device->dev_ref_cnt);
    free(st_device->dev_enable_cnt);
    list_for_each_safe(node, tmp_node, &st_device->sound_model_list) {
        st_session = node_to_item(node, st_session_t, list_node);
        list_remove(node);
        st_session_stop_lab(st_session);
        st_session_stop(st_session);
        if (!list_empty(&st_session->second_stage_list))
            st_session_ss_deinit(st_session);
        st_session_deinit(st_session);
        free(st_session->phrase_sm);
        free(st_session->rc_config);
        free(st_session);
    }

    pthread_mutex_unlock(&st_device->lock);
    hw_session_notifier_deinit();

    if (st_device->transit_to_adsp_on_playback ||
        st_device->transit_to_adsp_on_battery_charging) {
        st_device->stop_transitions_thread_loop = true;
        pthread_cond_signal(&st_device->transitions_cond);
        status = pthread_join(st_device->transitions_thread, NULL);
        if (status)
            ALOGE("%s: Error joining transitions thread. status = %d",
                __func__, status);
    }

    pthread_mutex_destroy(&st_device->lock);
    pthread_mutex_destroy(&st_device->ref_cnt_lock);
    free(device);
    stdev = NULL;

exit:
    pthread_mutex_unlock(&stdev_init_lock);
    ATRACE_END();
    ALOGD("%s: Exit device=%p cnt=%d ", __func__, st_device,
        stdev_ref_cnt);
    return 0;
}

static int stdev_stop_all_recognitions(const struct sound_trigger_hw_device* dev __unused)
{
    ALOGV("%s: unsupported API", __func__);
    return -ENOSYS;
}

static int stdev_get_parameter(const struct sound_trigger_hw_device *dev __unused,
    sound_model_handle_t sound_model_handle __unused,
    sound_trigger_model_parameter_t model_param __unused, int32_t* value __unused)
{
    ALOGV("%s: unsupported API", __func__);
    return -EINVAL;
}

static int stdev_set_parameter(const struct sound_trigger_hw_device *dev __unused,
    sound_model_handle_t sound_model_handle __unused,
    sound_trigger_model_parameter_t model_param __unused, int32_t value __unused)
{
    ALOGV("%s: unsupported API", __func__);
    return -EINVAL;
}

static int stdev_query_parameter(const struct sound_trigger_hw_device *dev __unused,
    sound_model_handle_t sound_model_handle __unused,
    sound_trigger_model_parameter_t  model_param __unused,
    sound_trigger_model_parameter_range_t* param_range)
{
    if (param_range)
        param_range->is_supported = false;
    return 0;
}

static const struct sound_trigger_properties_header*
stdev_get_properties_extended(const struct sound_trigger_hw_device *dev)
{
    struct st_vendor_info *v_info = NULL;
    struct listnode *v_node = NULL;
    struct sound_trigger_device *stdev = NULL;
    sound_model_handle_t handle = 0;
    st_session_t *st_session = NULL;
    struct sound_trigger_properties_header *prop_hdr = NULL;
    int status = 0;

    ALOGI("%s: enter", __func__);

    if (!dev) {
        ALOGW("%s: invalid sound_trigger_hw_device received", __func__);
        return NULL;
    }

    stdev = (struct sound_trigger_device *)dev;
    prop_hdr = (struct sound_trigger_properties_header *)&hw_properties_extended;
    get_base_properties(stdev);

    hw_properties_extended.header.size = sizeof(struct sound_trigger_properties_extended_1_3);
    hw_properties_extended.audio_capabilities = 0;
    hw_properties_extended.header.version = SOUND_TRIGGER_DEVICE_API_VERSION_1_3;

    /*
     * The below code is to get hotword algo version from ADSP. In case of any
     * errors in  getting the version, return base properties as its not harmful
     * to bail out STHAL feature with version failure.
     */

    pthread_mutex_lock(&stdev->lock);
    if (!CHECK_BIT(stdev->hw_type,
            ST_DEVICE_HW_APE|ST_DEVICE_HW_CPE|ST_DEVICE_HW_ARM)) {
        status = platform_stdev_get_hw_type(stdev->platform);
        if (status) {
            ALOGW("%s: get hw type failed, %d", __func__, status);
            goto exit_2;
        }
    }
    list_for_each(v_node, &stdev->vendor_uuid_list) {
        v_info = node_to_item(v_node, struct st_vendor_info, list_node);
        if (v_info->get_module_version) {
            st_session = calloc(1, sizeof(st_session_t));
            if (!st_session) {
                ALOGW("%s: st_session allocation failed", __func__);
                goto exit_2;
            }

            st_session->f_stage_version = ST_MODULE_TYPE_GMM;
            st_session->vendor_uuid_info = v_info;
            handle = android_atomic_inc(&stdev->session_id);

            status = st_session_init(st_session, stdev, ST_EXEC_MODE_ADSP, handle);
            if (status) {
                ALOGW("%s: failed to initialize st_session with error %d", __func__,
                      status);
                goto exit_1;
            }

            status = st_session_get_module_version(st_session, hw_properties_extended.supported_model_arch);
            if (status) {
                ALOGW("%s: failed to get module version with error %d", __func__,
                      status);
                goto exit;
            }
            ALOGV("%s: version is %s", __func__, hw_properties_extended.supported_model_arch);
            break;
        }
    }

    pthread_mutex_unlock(&stdev->lock);
    return prop_hdr;

exit:
    st_session_deinit(st_session);

exit_1:
    android_atomic_dec(&stdev->session_id);
    free(st_session);
    st_session = NULL;

exit_2:
    pthread_mutex_unlock(&stdev->lock);
    return prop_hdr;
}

static int stdev_open(const hw_module_t* module, const char* name,
                     hw_device_t** device)
{
    int status = 0;

    ALOGD("%s: Enter", __func__);
    ATRACE_BEGIN("sthal: stdev_open");

    if (strcmp(name, SOUND_TRIGGER_HARDWARE_INTERFACE) != 0) {
        ALOGE("%s: ERROR. wrong interface", __func__);
        status = -EINVAL;
        goto exit;
    }

    pthread_mutex_lock(&stdev_init_lock);
    if (stdev_ref_cnt != 0) {
        *device = &stdev->device.common;
        stdev_ref_cnt++;
        ATRACE_END();
        ALOGD("%s: returning existing stdev instance, exit", __func__);
        pthread_mutex_unlock(&stdev_init_lock);
        return status;
    }

    stdev = calloc(1, sizeof(struct sound_trigger_device));
    if (!stdev) {
        ALOGE("%s: ERROR. stdev alloc failed", __func__);
        status = -ENOMEM;
        goto exit;
    }

    stdev->hw_properties = &hw_properties;

    status = load_audio_hal();
    if (status)
        goto exit;

    stdev->platform = platform_stdev_init(stdev);
    if (!stdev->platform) {
        ALOGE("%s: ERROR. platform init failed", __func__);
        status = -ENODEV;
        goto exit_1;
    }

    stdev->ape_pcm_use_cases =
        calloc(stdev->max_ape_sessions, sizeof(struct use_case_info));

    if (!stdev->ape_pcm_use_cases) {
        ALOGE("%s: ERROR. Mem alloc failed for ape use cases", __func__);
        status = -ENODEV;
        goto exit_1;
    }

    /* Each arm session is associated with corresponding ec ref session */
    stdev->arm_pcm_use_cases =
        calloc(stdev->max_arm_sessions * 2, sizeof(struct use_case_info));

    if (!stdev->arm_pcm_use_cases) {
        ALOGE("%s: ERROR. Mem alloc failed for capture use cases", __func__);
        status = -ENODEV;
        goto exit_1;
    }

    stdev->dev_ref_cnt =
        calloc(ST_EXEC_MODE_MAX * ST_DEVICE_MAX, sizeof(int));

    if (!stdev->dev_ref_cnt) {
        ALOGE("%s: ERROR. Mem alloc failed dev ref cnt", __func__);
        status = -ENOMEM;
        goto exit_1;
    }

    stdev->dev_enable_cnt =
        calloc(ST_EXEC_MODE_MAX * ST_DEVICE_MAX, sizeof(int));

    if (!stdev->dev_enable_cnt) {
        ALOGE("%s: ERROR. Mem alloc failed dev enable cnt", __func__);
        status = -ENOMEM;
        goto exit_1;
    }

    if (hw_session_notifier_init(stdev_session_event_cb) < 0) {
        ALOGE("%s: Failed to initialize notifier", __func__);
        status = -ENOMEM;
        goto exit_1;
    }

    stdev->device.common.tag = HARDWARE_DEVICE_TAG;
    stdev->device.common.version = SOUND_TRIGGER_DEVICE_API_VERSION_1_3;
    stdev->device.common.module = (struct hw_module_t *) module;
    stdev->device.common.close = stdev_close;
    stdev->device.get_properties = stdev_get_properties;
    stdev->device.load_sound_model = stdev_load_sound_model;
    stdev->device.unload_sound_model = stdev_unload_sound_model;
    stdev->device.start_recognition = stdev_start_recognition;
    stdev->device.stop_recognition = stdev_stop_recognition;
    stdev->device.get_properties_extended = stdev_get_properties_extended;
    stdev->device.start_recognition_extended = stdev_start_recognition_extended;
    stdev->device.stop_all_recognitions = stdev_stop_all_recognitions;
    stdev->device.get_parameter = stdev_get_parameter;
    stdev->device.set_parameter = stdev_set_parameter;
    stdev->device.query_parameter = stdev_query_parameter;

#ifdef ST_SUPPORT_GET_MODEL_STATE
    stdev->device.get_model_state = stdev_get_model_state;
#endif
    stdev->session_id = 1;
    stdev->gcs_token = 1;
    stdev->exec_mode = ST_EXEC_MODE_MAX;
    stdev->client_req_exec_mode = ST_EXEC_MODE_NONE;
    list_init(&stdev->available_devices);
    platform_stdev_update_device_list(AUDIO_DEVICE_IN_BUILTIN_MIC, "",
        &stdev->available_devices, true);
    list_init(&stdev->ec_ref_dev_list);
    platform_stdev_update_device_list(AUDIO_DEVICE_OUT_SPEAKER, "",
        &stdev->ec_ref_dev_list, true);
    list_init(&stdev->active_rx_dev_list);
    platform_stdev_update_device_list(AUDIO_DEVICE_OUT_SPEAKER, "",
        &stdev->active_rx_dev_list, true);
    stdev->session_allowed = true;
    stdev->reset_backend = true;
    stdev->conc_voice_active = false;
    stdev->conc_voip_active = false;
    stdev->lpma_handle = -1;
    stdev->is_charging = false;
    stdev->lpi_enable = false;
    stdev->vad_enable = false;
    stdev->audio_ec_enabled = false;

    pthread_mutex_init(&stdev->lock, (const pthread_mutexattr_t *) NULL);
    pthread_mutex_init(&stdev->ref_cnt_lock, (const pthread_mutexattr_t*)NULL);
    list_init(&stdev->sound_model_list);

    if (stdev->transit_to_adsp_on_playback ||
        stdev->transit_to_adsp_on_battery_charging)
        init_transitions_thread();

    sthw_extn_lpma_init(stdev);
    dbg_trace_parse_max_lab_reads(); /*For trace log control*/
    *device = &stdev->device.common;
    stdev_ref_cnt++;
    pthread_mutex_unlock(&stdev_init_lock);

    get_base_properties(stdev);
    hw_properties_extended.header.size = sizeof(struct sound_trigger_properties_extended_1_3);
    hw_properties_extended.audio_capabilities = 0;
    hw_properties_extended.header.version = SOUND_TRIGGER_DEVICE_API_VERSION_1_3;

    ATRACE_END();
    return 0;

exit_1:
    if (stdev->dev_ref_cnt)
        free(stdev->dev_ref_cnt);

    if (stdev->dev_enable_cnt)
        free(stdev->dev_enable_cnt);

    if (stdev->arm_pcm_use_cases)
        free(stdev->arm_pcm_use_cases);

    if (stdev->ape_pcm_use_cases)
        free(stdev->ape_pcm_use_cases);

    if (stdev->audio_hal_handle)
        dlclose(stdev->audio_hal_handle);

    if (stdev->platform)
       platform_stdev_deinit(stdev->platform);

exit:

    if (stdev)
        free(stdev);
    stdev = NULL;
    *device = NULL;

    pthread_mutex_unlock(&stdev_init_lock);
    ATRACE_END();
    ALOGD("%s: Exit status %d", __func__, status);
    return status;
}

static int stdev_get_param_data(st_session_t *p_ses, audio_event_info_t* config)
{
    qsthw_get_param_payload_t payload;
    size_t payload_size = sizeof(qsthw_get_param_payload_t);
    size_t param_data_size;
    int ret = 0;
    char value[128] = "";

    ret = st_session_get_param_data(p_ses, config->u.st_get_param_data.param,
                (void *)&payload, payload_size, &param_data_size);
    if (ret) {
        ALOGE("%s: ERROR. fetching get param data %d", __func__, ret);
        return ret;
    }
    if (!strncmp(config->u.st_get_param_data.param, QSTHW_PARAMETER_CHANNEL_INDEX,
            sizeof(QSTHW_PARAMETER_CHANNEL_INDEX))) {
        struct qsthw_target_channel_index_param ch_index_params =
                payload.ch_index_params;
        if (param_data_size != sizeof(struct qsthw_target_channel_index_param)) {
            ALOGE("%s: ERROR. Invalid param data size returned %zd",
                    __func__, param_data_size);
            return -EINVAL;
        }
        ALOGD("%s: target channel index - [%d]", __func__,
                ch_index_params.target_chan_idx);
        str_parms_add_int(config->u.st_get_param_data.reply,
                QSTHW_PARAMETER_CHANNEL_INDEX, ch_index_params.target_chan_idx);
    } else if (!strncmp(config->u.st_get_param_data.param, QSTHW_PARAMETER_DIRECTION_OF_ARRIVAL,
            sizeof(QSTHW_PARAMETER_DIRECTION_OF_ARRIVAL))) {
        struct qsthw_source_tracking_param st_params = payload.st_params;
        if (param_data_size != sizeof(struct qsthw_source_tracking_param)) {
            ALOGE("%s: ERROR. Invalid param data size returned %zd",
                    __func__, param_data_size);
            return -EINVAL;
        }
        ALOGD("%s: target angle boundaries [%d, %d]\n", __func__,
            st_params.target_angle_L16[0], st_params.target_angle_L16[1]);
        ALOGD("%s: interference angle boundaries [%d, %d]\n", __func__,
            st_params.interf_angle_L16[0], st_params.interf_angle_L16[1]);
        /*
         * To Do: Send polarActivityGUI data also to client
         */
        snprintf(value, sizeof(value), "target_angle: [%d, %d], interf_angle :[%d, %d]",
            st_params.target_angle_L16[0], st_params.target_angle_L16[0],
            st_params.interf_angle_L16[0], st_params.interf_angle_L16[0]);
        str_parms_add_str(config->u.st_get_param_data.reply,
                QSTHW_PARAMETER_DIRECTION_OF_ARRIVAL, value);
    } else {
        ALOGE("%s: Invalid get param", __func__);
    }
    return ret;
}

/*
 * Audio hal calls this callback for notifying Subsystem restart,
 * lab stop and concurrency events
 */
int sound_trigger_hw_call_back(audio_event_type_t event,
                               audio_event_info_t* config)
{
    struct listnode *p_ses_node = NULL;
    st_session_t *p_ses = NULL;
    int ret = 0;
    size_t bytes_read = 0;
    st_exec_mode_t exec_mode = 0;
    sound_model_handle_t sm_handle = 0;

    pthread_mutex_lock(&stdev_init_lock);
    if (!stdev) {
        pthread_mutex_unlock(&stdev_init_lock);
        return -ENODEV;
    }

    switch (event) {
    case AUDIO_EVENT_PLAYBACK_STREAM_INACTIVE:
    case AUDIO_EVENT_PLAYBACK_STREAM_ACTIVE:
        ATRACE_BEGIN("sthal: handle_echo_ref_switch");
        handle_echo_ref_switch(event, config);
        ATRACE_END();
        /* fall through */
    case AUDIO_EVENT_CAPTURE_DEVICE_INACTIVE:
    case AUDIO_EVENT_CAPTURE_DEVICE_ACTIVE:
        ATRACE_BEGIN("sthal: handle_audio_concurrency");
        handle_audio_concurrency(event, config);
        ATRACE_END();
        break;

    case AUDIO_EVENT_CAPTURE_STREAM_INACTIVE:
    case AUDIO_EVENT_CAPTURE_STREAM_ACTIVE:
        if (!config) {
            ALOGE("%s: NULL capture stream event config", __func__);
            ret = -EINVAL;
        } else {
            handle_audio_concurrency(event, config);
        }
        break;

    case AUDIO_EVENT_UPDATE_ECHO_REF:
        handle_audio_ec_ref_enabled(config);
        break;

    case AUDIO_EVENT_STOP_LAB:
        if (!config || !config->u.ses_info.p_ses) {
            ALOGE("%s: NULL params for stop lab", __func__);
            ret = -EINVAL;
            break;
        }
        ATRACE_BEGIN("sthal: event_stop_lab");
        p_ses = config->u.ses_info.p_ses;
        pthread_mutex_lock(&stdev->lock);

        /* check capture_handle to ensure pointer sanity */
        list_for_each(p_ses_node, &stdev->sound_model_list) {
            p_ses = node_to_item(p_ses_node, st_session_t, list_node);
            if (p_ses->capture_handle == config->u.ses_info.capture_handle) {
                st_session_stop_lab(p_ses);
                break;
            }
        }
        pthread_mutex_unlock(&stdev->lock);
        ATRACE_END();
        break;

    case AUDIO_EVENT_SSR:
        if (!config) {
            ALOGE("%s: NULL config for SSR", __func__);
            ret = -EINVAL;
            break;
        }

        if ((config->u.status == SND_CARD_STATUS_OFFLINE) ||
            (config->u.status == CPE_STATUS_OFFLINE) ||
            (config->u.status == SLPI_STATUS_OFFLINE))
            handle_ssr_offline(config->u.status);

        if ((config->u.status == SND_CARD_STATUS_ONLINE) ||
            (config->u.status == CPE_STATUS_ONLINE) ||
            (config->u.status == SLPI_STATUS_ONLINE))
            handle_ssr_online(config->u.status);
        break;

    case AUDIO_EVENT_NUM_ST_SESSIONS:
        if (!config) {
            ALOGE("%s: NULL config for AUDIO_EVENT_NUM_ST_SESSIONS", __func__);
            ret = -EINVAL;
            break;
        }
        pthread_mutex_lock(&stdev->lock);
        ALOGV("%s: num sessions configured %d", __func__, config->u.value);
        stdev->num_sessions_configured = config->u.value;
        pthread_mutex_unlock(&stdev->lock);
        break;

    case AUDIO_EVENT_READ_SAMPLES:
        if (!config) {
            ALOGE("%s: Invalid config", __func__);
            ret = -EINVAL;
            break;
        }
        p_ses = (st_session_t*)config->u.aud_info.ses_info->p_ses;
        ret = st_session_read_pcm(p_ses, config->u.aud_info.buf,
            config->u.aud_info.num_bytes,
            &bytes_read);
        break;

    case AUDIO_EVENT_DEVICE_CONNECT:
        if (!config) {
            ALOGE("%s: NULL config for DEVICE_CONNECT", __func__);
            ret = -EINVAL;
            break;
        }
        if (config->u.value == AUDIO_DEVICE_OUT_LINE ||
            config->u.value == AUDIO_DEVICE_OUT_BLUETOOTH_A2DP ||
            config->u.value == AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES ||
            config->u.value == AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER) {
            pthread_mutex_lock(&stdev->lock);
            platform_stdev_update_device_list(config->u.value, "",
                &stdev->ec_ref_dev_list, true);
            pthread_mutex_unlock(&stdev->lock);
            ALOGD("%s: Device connected. Updated ec ref devices with %d",
                  __func__, config->u.value);
        } else {
            handle_device_switch(true, config);
        }
        break;

    case AUDIO_EVENT_DEVICE_DISCONNECT:
        if (!config) {
            ALOGE("%s: NULL config for DEVICE_DISCONNECT", __func__);
            ret = -EINVAL;
            break;
        }
        if (config->u.value == AUDIO_DEVICE_OUT_LINE ||
            config->u.value == AUDIO_DEVICE_OUT_BLUETOOTH_A2DP ||
            config->u.value == AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES ||
            config->u.value == AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER) {
            pthread_mutex_lock(&stdev->lock);
            /*
             * Currently spkr/lineout/a2dp are the supported ec ref devices
             * Set default EC ref device (spkr) if lineout/a2dp is disconnected
             */
            platform_stdev_update_device_list(config->u.value, "",
                &stdev->ec_ref_dev_list, false);
            pthread_mutex_unlock(&stdev->lock);
            ALOGD("%s: Device disconnected. Updated ec ref devices by removing %d",
                  __func__, config->u.value);
        } else {
            handle_device_switch(false, config);
        }
        break;

    case AUDIO_EVENT_SVA_EXEC_MODE:
        pthread_mutex_lock(&stdev->lock);
        if (!config) {
            ALOGE("%s: NULL config for AUDIO_EVENT_SVA_EXEC_MODE", __func__);
            ret = -EINVAL;
            goto error;
        }
        ret = parse_exec_mode_config(config->u.str_value, &exec_mode, &sm_handle);
        if (ret) {
            ALOGE("%s: Failed to parse exec mode config", __func__);
            goto error;
        }

        if (sm_handle) {
            p_ses = get_sound_trigger_session(stdev, sm_handle);
            if (p_ses == NULL) {
                ALOGE("%s: Could not find sound model %d", __func__, sm_handle);
                ret = -EINVAL;
                goto error;
            }
        }
        ALOGV("%s:[%d] set exec mode %d", __func__, sm_handle, exec_mode);
        if (exec_mode == ST_EXEC_MODE_ADSP) {
            ret = check_and_transit_cpe_ses_to_ape(p_ses);
            if (!sm_handle)
                stdev->client_req_exec_mode = exec_mode;
        } else if (exec_mode == ST_EXEC_MODE_CPE) {
            ret = check_and_transit_ape_ses_to_cpe(p_ses);
            if (!sm_handle)
                stdev->client_req_exec_mode = exec_mode;
        } else {
            ALOGE("%s: Invalid exec mode %d", __func__, exec_mode);
            ret = -EINVAL;
        }

    error:
        /* store exec mode callback status to return when queried */
        stdev->client_req_exec_mode_status = ret;
        pthread_mutex_unlock(&stdev->lock);
        break;

    case AUDIO_EVENT_SVA_EXEC_MODE_STATUS:
        if (!config) {
            ALOGE("%s: NULL config for AUDIO_EVENT_SVA_EXEC_MODE", __func__);
            ret = -EINVAL;
            break;
        }
        config->u.value = stdev->client_req_exec_mode_status;
        ALOGV("%s: exec mode status %d", __func__, config->u.value);
        break;

    case AUDIO_EVENT_GET_PARAM:
        if (!config || !(config->u.st_get_param_data.reply)) {
            ALOGE("%s: NULL config for AUDIO_EVENT_GET_PARAM", __func__);
            ret = -EINVAL;
            break;
        }
        ALOGD("%s: get param data for %s with sm_handle %d", __func__,
            config->u.st_get_param_data.param, config->u.st_get_param_data.sm_handle);
        pthread_mutex_lock(&stdev->lock);
        p_ses = get_sound_trigger_session(stdev, config->u.st_get_param_data.sm_handle);
        if (!p_ses) {
            ALOGE("%s: ERROR. Could not find session for sm_handle %d",
                    __func__, config->u.st_get_param_data.sm_handle);
            ret = -EINVAL;
            goto exit;
        }
        ret = stdev_get_param_data(p_ses, config);
    exit:
        pthread_mutex_unlock(&stdev->lock);
        ALOGV("%s: exit: return - %d", __func__, ret);
        break;

    case AUDIO_EVENT_BATTERY_STATUS_CHANGED:
        if (!config) {
            ALOGE("%s: NULL config for AUDIO_EVENT_BATTERY_STATUS_CHANGED", __func__);
            ret = -EINVAL;
            break;
        }
        handle_battery_status_change(config);
        break;

    case AUDIO_EVENT_SCREEN_STATUS_CHANGED:
        if (!config) {
            ALOGE("%s: NULL config for AUDIO_EVENT_SCREEN_STATUS_CHANGED", __func__);
            ret = -EINVAL;
            break;
        }
        handle_screen_status_change(config);
        break;

    default:
        ALOGW("%s: Unknown event %d", __func__, event);
        break;
    }

    pthread_mutex_unlock(&stdev_init_lock);
    return ret;
}

/*
 * Current proprietary API version used by STHAL. Queried by AHAL
 * for compatibility check with STHAL
 */
const unsigned int sthal_prop_api_version = STHAL_PROP_API_CURRENT_VERSION;

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

struct sound_trigger_module HAL_MODULE_INFO_SYM = {
    .common = {
        .tag = HARDWARE_MODULE_TAG,
        .module_api_version = SOUND_TRIGGER_MODULE_API_VERSION_1_0,
        .hal_api_version = HARDWARE_HAL_API_VERSION,
        .id = SOUND_TRIGGER_HARDWARE_MODULE_ID,
        .name = "Sound trigger HAL",
        .author = "QUALCOMM Technologies, Inc",
        .methods = &hal_module_methods,
    },
};
