127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent/*
227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent * Copyright (C) 2016 The Android Open Source Project
327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent *
427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent * Licensed under the Apache License, Version 2.0 (the "License");
527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent * you may not use this file except in compliance with the License.
627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent * You may obtain a copy of the License at
727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent *
827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent *      http://www.apache.org/licenses/LICENSE-2.0
927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent *
1027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent * Unless required by applicable law or agreed to in writing, software
1127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent * distributed under the License is distributed on an "AS IS" BASIS,
1227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent * See the License for the specific language governing permissions and
1427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent * limitations under the License.
1527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent */
1627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
1727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent#define LOG_TAG "SoundTriggerHalImpl"
1827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent//#define LOG_NDEBUG 0
1927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
20f9d303435d80161fabb16cdff3b8f2f75f362480Yifan Hong#include <android/log.h>
2127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent#include "SoundTriggerHalImpl.h"
2227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
2327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
2427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurentnamespace android {
2527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurentnamespace hardware {
2627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurentnamespace soundtrigger {
2727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurentnamespace V2_0 {
2827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurentnamespace implementation {
2927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
3027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent// static
3127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurentvoid SoundTriggerHalImpl::soundModelCallback(struct sound_trigger_model_event *halEvent,
3227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent                                               void *cookie)
3327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent{
3427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    if (halEvent == NULL) {
3527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        ALOGW("soundModelCallback called with NULL event");
3627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        return;
3727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    }
3827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    sp<SoundModelClient> client =
3927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent            wp<SoundModelClient>(static_cast<SoundModelClient *>(cookie)).promote();
4027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    if (client == 0) {
4127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        ALOGW("soundModelCallback called on stale client");
4227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        return;
4327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    }
4427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    if (halEvent->model != client->mHalHandle) {
4527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        ALOGW("soundModelCallback call with wrong handle %d on client with handle %d",
4627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent              (int)halEvent->model, (int)client->mHalHandle);
4727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        return;
4827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    }
4927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
5027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    ISoundTriggerHwCallback::ModelEvent event;
5127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    convertSoundModelEventFromHal(&event, halEvent);
5227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    event.model = client->mId;
5327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
5427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    client->mCallback->soundModelCallback(event, client->mCookie);
5527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent}
5627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
5727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent// static
5827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurentvoid SoundTriggerHalImpl::recognitionCallback(struct sound_trigger_recognition_event *halEvent,
5927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent                                               void *cookie)
6027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent{
6127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    if (halEvent == NULL) {
6227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        ALOGW("recognitionCallback call NULL event");
6327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        return;
6427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    }
6527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    sp<SoundModelClient> client =
6627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent            wp<SoundModelClient>(static_cast<SoundModelClient *>(cookie)).promote();
6727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    if (client == 0) {
6827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        ALOGW("soundModelCallback called on stale client");
6927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        return;
7027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    }
7127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
7227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    ISoundTriggerHwCallback::RecognitionEvent *event = convertRecognitionEventFromHal(halEvent);
7327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    event->model = client->mId;
7427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    if (halEvent->type == SOUND_MODEL_TYPE_KEYPHRASE) {
7527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        client->mCallback->phraseRecognitionCallback(
7627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent                *(reinterpret_cast<ISoundTriggerHwCallback::PhraseRecognitionEvent *>(event)),
7727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent                client->mCookie);
7827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    } else {
7927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        client->mCallback->recognitionCallback(*event, client->mCookie);
8027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    }
8127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    delete event;
8227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent}
8327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
8427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
8527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
8627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent// Methods from ::android::hardware::soundtrigger::V2_0::ISoundTriggerHw follow.
8727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric LaurentReturn<void> SoundTriggerHalImpl::getProperties(getProperties_cb _hidl_cb)
8827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent{
8927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    ALOGV("getProperties() mHwDevice %p", mHwDevice);
9027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    int ret;
9127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    struct sound_trigger_properties halProperties;
9227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    ISoundTriggerHw::Properties properties;
9327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
9427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    if (mHwDevice == NULL) {
9527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        ret = -ENODEV;
9627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        goto exit;
9727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    }
9827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
9927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    ret = mHwDevice->get_properties(mHwDevice, &halProperties);
10027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
10127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    convertPropertiesFromHal(&properties, &halProperties);
10227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
10327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    ALOGV("getProperties implementor %s recognitionModes %08x",
10427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent          properties.implementor.c_str(), properties.recognitionModes);
10527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
10627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurentexit:
10727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    _hidl_cb(ret, properties);
10827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    return Void();
10927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent}
11027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
11127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurentint SoundTriggerHalImpl::doLoadSoundModel(const ISoundTriggerHw::SoundModel& soundModel,
11227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent                                                 const sp<ISoundTriggerHwCallback>& callback,
11327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent                                                 ISoundTriggerHwCallback::CallbackCookie cookie,
11427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent                                                 uint32_t *modelId)
11527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent{
11627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    int32_t ret = 0;
11727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    struct sound_trigger_sound_model *halSoundModel;
11827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    *modelId = 0;
11927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    sp<SoundModelClient> client;
12027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
12127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    ALOGV("doLoadSoundModel() data size %zu", soundModel.data.size());
12227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
12327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    if (mHwDevice == NULL) {
12427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        ret = -ENODEV;
12527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        goto exit;
12627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    }
12727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
12827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    halSoundModel = convertSoundModelToHal(&soundModel);
12927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    if (halSoundModel == NULL) {
13027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        ret = -EINVAL;
13127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        goto exit;
13227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    }
13327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
13427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    {
13527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        AutoMutex lock(mLock);
13627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        do {
13727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent            *modelId = nextUniqueId();
13827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        } while (mClients.valueFor(*modelId) != 0 && *modelId != 0);
13927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    }
14027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    LOG_ALWAYS_FATAL_IF(*modelId == 0,
14106e939be44d093ce756c624e7be7341c12ae0282Bryan Eyler                        "wrap around in sound model IDs, num loaded models %zu", mClients.size());
14227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
14327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    client = new SoundModelClient(*modelId, callback, cookie);
14427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
14527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    ret = mHwDevice->load_sound_model(mHwDevice, halSoundModel, soundModelCallback,
14627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent                                          client.get(), &client->mHalHandle);
14727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
14827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    free(halSoundModel);
14927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
15027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    if (ret != 0) {
15127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        goto exit;
15227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    }
15327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
15427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    {
15527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        AutoMutex lock(mLock);
15627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        mClients.add(*modelId, client);
15727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    }
15827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
15927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurentexit:
16027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    return ret;
16127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent}
16227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
16327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric LaurentReturn<void> SoundTriggerHalImpl::loadSoundModel(const ISoundTriggerHw::SoundModel& soundModel,
16427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent                                                 const sp<ISoundTriggerHwCallback>& callback,
16527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent                                                 ISoundTriggerHwCallback::CallbackCookie cookie,
16627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent                                                 loadSoundModel_cb _hidl_cb)
16727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent{
16827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    uint32_t modelId = 0;
16927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    int32_t ret = doLoadSoundModel(soundModel, callback, cookie, &modelId);
17027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
17127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    _hidl_cb(ret, modelId);
17227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    return Void();
17327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent}
17427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
17527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric LaurentReturn<void> SoundTriggerHalImpl::loadPhraseSoundModel(
17627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent                                            const ISoundTriggerHw::PhraseSoundModel& soundModel,
17727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent                                            const sp<ISoundTriggerHwCallback>& callback,
17827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent                                            ISoundTriggerHwCallback::CallbackCookie cookie,
17927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent                                            ISoundTriggerHw::loadPhraseSoundModel_cb _hidl_cb)
18027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent{
18127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    uint32_t modelId = 0;
18227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    int32_t ret = doLoadSoundModel((const ISoundTriggerHw::SoundModel&)soundModel,
18327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent                                   callback, cookie, &modelId);
18427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
18527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    _hidl_cb(ret, modelId);
18627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    return Void();
18727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent}
18827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
18927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric LaurentReturn<int32_t> SoundTriggerHalImpl::unloadSoundModel(SoundModelHandle modelHandle)
19027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent{
19127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    int32_t ret;
19227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    sp<SoundModelClient> client;
19327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
19427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    if (mHwDevice == NULL) {
19527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        ret = -ENODEV;
19627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        goto exit;
19727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    }
19827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
19927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    {
20027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        AutoMutex lock(mLock);
20127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        client = mClients.valueFor(modelHandle);
20227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        if (client == 0) {
20327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent            ret = -ENOSYS;
20427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent            goto exit;
20527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        }
20627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    }
20727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
20827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    ret = mHwDevice->unload_sound_model(mHwDevice, client->mHalHandle);
20927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
21027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    mClients.removeItem(modelHandle);
21127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
21227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurentexit:
21327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    return ret;
21427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent}
21527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
21627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric LaurentReturn<int32_t> SoundTriggerHalImpl::startRecognition(SoundModelHandle modelHandle,
21727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent                                           const ISoundTriggerHw::RecognitionConfig& config,
21827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent                                           const sp<ISoundTriggerHwCallback>& callback __unused,
21927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent                                           ISoundTriggerHwCallback::CallbackCookie cookie __unused)
22027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent{
22127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    int32_t ret;
22227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    sp<SoundModelClient> client;
22327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    struct sound_trigger_recognition_config *halConfig;
22427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
22527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    if (mHwDevice == NULL) {
22627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        ret = -ENODEV;
22727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        goto exit;
22827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    }
22927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
23027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    {
23127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        AutoMutex lock(mLock);
23227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        client = mClients.valueFor(modelHandle);
23327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        if (client == 0) {
23427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent            ret = -ENOSYS;
23527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent            goto exit;
23627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        }
23727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    }
23827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
23927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
24027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    halConfig = convertRecognitionConfigToHal(&config);
24127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
24227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    if (halConfig == NULL) {
24327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        ret = -EINVAL;
24427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        goto exit;
24527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    }
24627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    ret = mHwDevice->start_recognition(mHwDevice, client->mHalHandle, halConfig,
24727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent                                 recognitionCallback, client.get());
24827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
24927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    free(halConfig);
25027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
25127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurentexit:
25227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    return ret;
25327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent}
25427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
25527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric LaurentReturn<int32_t> SoundTriggerHalImpl::stopRecognition(SoundModelHandle modelHandle)
25627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent{
25727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    int32_t ret;
25827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    sp<SoundModelClient> client;
25927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    if (mHwDevice == NULL) {
26027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        ret = -ENODEV;
26127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        goto exit;
26227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    }
26327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
26427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    {
26527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        AutoMutex lock(mLock);
26627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        client = mClients.valueFor(modelHandle);
26727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        if (client == 0) {
26827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent            ret = -ENOSYS;
26927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent            goto exit;
27027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        }
27127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    }
27227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
27327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    ret = mHwDevice->stop_recognition(mHwDevice, client->mHalHandle);
27427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
27527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurentexit:
27627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    return ret;
27727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent}
27827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
27927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric LaurentReturn<int32_t> SoundTriggerHalImpl::stopAllRecognitions()
28027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent{
28127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    int32_t ret;
28227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    if (mHwDevice == NULL) {
28327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        ret = -ENODEV;
28427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        goto exit;
28527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    }
28627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
28727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    if (mHwDevice->common.version >= SOUND_TRIGGER_DEVICE_API_VERSION_1_1 &&
28827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent            mHwDevice->stop_all_recognitions) {
28927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        ret = mHwDevice->stop_all_recognitions(mHwDevice);
29027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    } else {
29127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        ret = -ENOSYS;
29227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    }
29327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurentexit:
29427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    return ret;
29527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent}
29627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
2973acaa668c102cf096a9e3bc540d7a74ca3ac5c36Mikhail NaganovSoundTriggerHalImpl::SoundTriggerHalImpl()
2983acaa668c102cf096a9e3bc540d7a74ca3ac5c36Mikhail Naganov    : mModuleName("primary"), mHwDevice(NULL), mNextModelId(1)
29927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent{
30027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent}
30127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
30227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurentvoid SoundTriggerHalImpl::onFirstRef()
30327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent{
30427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    const hw_module_t *mod;
30527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    int rc;
30627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
30727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    rc = hw_get_module_by_class(SOUND_TRIGGER_HARDWARE_MODULE_ID, mModuleName, &mod);
30827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    if (rc != 0) {
30927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        ALOGE("couldn't load sound trigger module %s.%s (%s)",
31027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent              SOUND_TRIGGER_HARDWARE_MODULE_ID, mModuleName, strerror(-rc));
31127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        return;
31227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    }
31327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    rc = sound_trigger_hw_device_open(mod, &mHwDevice);
31427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    if (rc != 0) {
31527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        ALOGE("couldn't open sound trigger hw device in %s.%s (%s)",
31627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent              SOUND_TRIGGER_HARDWARE_MODULE_ID, mModuleName, strerror(-rc));
31727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        mHwDevice = NULL;
31827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        return;
31927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    }
32027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    if (mHwDevice->common.version < SOUND_TRIGGER_DEVICE_API_VERSION_1_0 ||
32127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent            mHwDevice->common.version > SOUND_TRIGGER_DEVICE_API_VERSION_CURRENT) {
32227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        ALOGE("wrong sound trigger hw device version %04x", mHwDevice->common.version);
32327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        sound_trigger_hw_device_close(mHwDevice);
32427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        mHwDevice = NULL;
32527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        return;
32627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    }
32727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
32827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    ALOGI("onFirstRef() mModuleName %s mHwDevice %p", mModuleName, mHwDevice);
32927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent}
33027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
33127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric LaurentSoundTriggerHalImpl::~SoundTriggerHalImpl()
33227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent{
33327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    if (mHwDevice != NULL) {
33427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        sound_trigger_hw_device_close(mHwDevice);
33527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    }
33627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent}
33727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
33827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurentuint32_t SoundTriggerHalImpl::nextUniqueId()
33927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent{
34027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    return (uint32_t) atomic_fetch_add_explicit(&mNextModelId,
34127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent                (uint_fast32_t) 1, memory_order_acq_rel);
34227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent}
34327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
34427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurentvoid SoundTriggerHalImpl::convertUuidFromHal(Uuid *uuid,
34527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent                                             const sound_trigger_uuid_t *halUuid)
34627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent{
34727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    uuid->timeLow = halUuid->timeLow;
34827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    uuid->timeMid = halUuid->timeMid;
34927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    uuid->versionAndTimeHigh = halUuid->timeHiAndVersion;
35027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    uuid->variantAndClockSeqHigh = halUuid->clockSeq;
35127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    memcpy(&uuid->node[0], &halUuid->node[0], 6);
35227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent}
35327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
35427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurentvoid SoundTriggerHalImpl::convertUuidToHal(sound_trigger_uuid_t *halUuid,
35527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent                                           const Uuid *uuid)
35627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent{
35727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    halUuid->timeLow = uuid->timeLow;
35827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    halUuid->timeMid = uuid->timeMid;
35927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    halUuid->timeHiAndVersion = uuid->versionAndTimeHigh;
36027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    halUuid->clockSeq = uuid->variantAndClockSeqHigh;
36127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    memcpy(&halUuid->node[0], &uuid->node[0], 6);
36227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent}
36327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
36427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurentvoid SoundTriggerHalImpl::convertPropertiesFromHal(
36527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        ISoundTriggerHw::Properties *properties,
36627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        const struct sound_trigger_properties *halProperties)
36727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent{
36827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    properties->implementor = halProperties->implementor;
36927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    properties->description = halProperties->description;
37027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    properties->version = halProperties->version;
37127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    convertUuidFromHal(&properties->uuid, &halProperties->uuid);
37227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    properties->maxSoundModels = halProperties->max_sound_models;
37327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    properties->maxKeyPhrases = halProperties->max_key_phrases;
37427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    properties->maxUsers = halProperties->max_users;
37527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    properties->recognitionModes = halProperties->recognition_modes;
37627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    properties->captureTransition = halProperties->capture_transition;
37727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    properties->maxBufferMs = halProperties->max_buffer_ms;
37827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    properties->concurrentCapture = halProperties->concurrent_capture;
37927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    properties->triggerInEvent = halProperties->trigger_in_event;
38027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    properties->powerConsumptionMw = halProperties->power_consumption_mw;
38127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
38227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent}
38327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
38427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurentvoid SoundTriggerHalImpl::convertTriggerPhraseToHal(
38527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        struct sound_trigger_phrase *halTriggerPhrase,
38627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        const ISoundTriggerHw::Phrase *triggerPhrase)
38727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent{
38827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    halTriggerPhrase->id = triggerPhrase->id;
38927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    halTriggerPhrase->recognition_mode = triggerPhrase->recognitionModes;
39027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    unsigned int i;
39127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    for (i = 0; i < triggerPhrase->users.size(); i++) {
39227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        halTriggerPhrase->users[i] = triggerPhrase->users[i];
39327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    }
39427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    halTriggerPhrase->num_users = i;
39527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
39627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    strlcpy(halTriggerPhrase->locale,
39727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent            triggerPhrase->locale.c_str(), SOUND_TRIGGER_MAX_LOCALE_LEN);
39827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    strlcpy(halTriggerPhrase->text,
39927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent            triggerPhrase->text.c_str(), SOUND_TRIGGER_MAX_STRING_LEN);
40027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent}
40127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
40227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurentstruct sound_trigger_sound_model *SoundTriggerHalImpl::convertSoundModelToHal(
40327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        const ISoundTriggerHw::SoundModel *soundModel)
40427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent{
40527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    struct sound_trigger_sound_model *halModel = NULL;
40627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    if (soundModel->type == SoundModelType::KEYPHRASE) {
40727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        size_t allocSize =
40827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent                sizeof(struct sound_trigger_phrase_sound_model) + soundModel->data.size();
40927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        struct sound_trigger_phrase_sound_model *halKeyPhraseModel =
41027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent                static_cast<struct sound_trigger_phrase_sound_model *>(malloc(allocSize));
41127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        LOG_ALWAYS_FATAL_IF(halKeyPhraseModel == NULL,
41227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent                        "malloc failed for size %zu in convertSoundModelToHal PHRASE", allocSize);
41327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
41427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        const ISoundTriggerHw::PhraseSoundModel *keyPhraseModel =
41527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent                reinterpret_cast<const ISoundTriggerHw::PhraseSoundModel *>(soundModel);
41627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
41727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        size_t i;
41827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        for (i = 0; i < keyPhraseModel->phrases.size() && i < SOUND_TRIGGER_MAX_PHRASES; i++) {
41927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent            convertTriggerPhraseToHal(&halKeyPhraseModel->phrases[i],
42027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent                                      &keyPhraseModel->phrases[i]);
42127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        }
42227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        halKeyPhraseModel->num_phrases = (unsigned int)i;
42327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        halModel = reinterpret_cast<struct sound_trigger_sound_model *>(halKeyPhraseModel);
42427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        halModel->data_offset = sizeof(struct sound_trigger_phrase_sound_model);
42527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    } else {
42627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        size_t allocSize =
42727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent                sizeof(struct sound_trigger_sound_model) + soundModel->data.size();
42827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        halModel = static_cast<struct sound_trigger_sound_model *>(malloc(allocSize));
42927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        LOG_ALWAYS_FATAL_IF(halModel == NULL,
43027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent                            "malloc failed for size %zu in convertSoundModelToHal GENERIC",
43127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent                            allocSize);
43227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
43327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        halModel->data_offset = sizeof(struct sound_trigger_sound_model);
43427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    }
43527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    halModel->type = (sound_trigger_sound_model_type_t)soundModel->type;
43627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    convertUuidToHal(&halModel->uuid, &soundModel->uuid);
43727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    convertUuidToHal(&halModel->vendor_uuid, &soundModel->vendorUuid);
43827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    halModel->data_size = soundModel->data.size();
43927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    uint8_t *dst = reinterpret_cast<uint8_t *>(halModel) + halModel->data_offset;
44027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    const uint8_t *src = reinterpret_cast<const uint8_t *>(&soundModel->data[0]);
44127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    memcpy(dst, src, soundModel->data.size());
44227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
44327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    return halModel;
44427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent}
44527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
44627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurentvoid SoundTriggerHalImpl::convertPhraseRecognitionExtraToHal(
44727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        struct sound_trigger_phrase_recognition_extra *halExtra,
44827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        const PhraseRecognitionExtra *extra)
44927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent{
45027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    halExtra->id = extra->id;
45127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    halExtra->recognition_modes = extra->recognitionModes;
45227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    halExtra->confidence_level = extra->confidenceLevel;
45327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
45427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    unsigned int i;
45527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    for (i = 0; i < extra->levels.size() && i < SOUND_TRIGGER_MAX_USERS; i++) {
45627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        halExtra->levels[i].user_id = extra->levels[i].userId;
45727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        halExtra->levels[i].level = extra->levels[i].levelPercent;
45827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    }
45927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    halExtra->num_levels = i;
46027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent}
46127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
46227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurentstruct sound_trigger_recognition_config *SoundTriggerHalImpl::convertRecognitionConfigToHal(
46327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        const ISoundTriggerHw::RecognitionConfig *config)
46427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent{
46527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    size_t allocSize = sizeof(struct sound_trigger_recognition_config) + config->data.size();
46627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    struct sound_trigger_recognition_config *halConfig =
46727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent            static_cast<struct sound_trigger_recognition_config *>(malloc(allocSize));
46827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
46927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    LOG_ALWAYS_FATAL_IF(halConfig == NULL,
47027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent                        "malloc failed for size %zu in convertRecognitionConfigToHal",
47127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent                        allocSize);
47227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
47327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    halConfig->capture_handle = (audio_io_handle_t)config->captureHandle;
47427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    halConfig->capture_device = (audio_devices_t)config->captureDevice;
47527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    halConfig->capture_requested = config->captureRequested;
47627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
47727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    unsigned int i;
47827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    for (i = 0; i < config->phrases.size() && i < SOUND_TRIGGER_MAX_PHRASES; i++) {
47927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        convertPhraseRecognitionExtraToHal(&halConfig->phrases[i],
48027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent                                  &config->phrases[i]);
48127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    }
48227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    halConfig->num_phrases = i;
48327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
48427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    halConfig->data_offset = sizeof(struct sound_trigger_recognition_config);
48527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    halConfig->data_size = config->data.size();
48627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    uint8_t *dst = reinterpret_cast<uint8_t *>(halConfig) + halConfig->data_offset;
48727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    const uint8_t *src = reinterpret_cast<const uint8_t *>(&config->data[0]);
48827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    memcpy(dst, src, config->data.size());
48927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    return halConfig;
49027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent}
49127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
49227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent// static
49327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurentvoid SoundTriggerHalImpl::convertSoundModelEventFromHal(ISoundTriggerHwCallback::ModelEvent *event,
49427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent                                                const struct sound_trigger_model_event *halEvent)
49527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent{
49627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    event->status = (ISoundTriggerHwCallback::SoundModelStatus)halEvent->status;
49727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    // event->model to be remapped by called
49827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    event->data.setToExternal(
49927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent            const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(halEvent)) + halEvent->data_offset,
50027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent            halEvent->data_size);
50127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent}
50227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
50327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent// static
50427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric LaurentISoundTriggerHwCallback::RecognitionEvent *SoundTriggerHalImpl::convertRecognitionEventFromHal(
50527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent                                            const struct sound_trigger_recognition_event *halEvent)
50627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent{
50727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    ISoundTriggerHwCallback::RecognitionEvent * event;
50827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
50927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    if (halEvent->type == SOUND_MODEL_TYPE_KEYPHRASE) {
51027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        const struct sound_trigger_phrase_recognition_event *halPhraseEvent =
51127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent                reinterpret_cast<const struct sound_trigger_phrase_recognition_event *>(halEvent);
51227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        ISoundTriggerHwCallback::PhraseRecognitionEvent *phraseEvent =
51327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent                new ISoundTriggerHwCallback::PhraseRecognitionEvent();
51427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
51527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        PhraseRecognitionExtra *phraseExtras =
51627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent                new PhraseRecognitionExtra[halPhraseEvent->num_phrases];
51727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        for (unsigned int i = 0; i < halPhraseEvent->num_phrases; i++) {
51827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent            convertPhraseRecognitionExtraFromHal(&phraseExtras[i],
51927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent                                                 &halPhraseEvent->phrase_extras[i]);
52027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        }
52127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        phraseEvent->phraseExtras.setToExternal(phraseExtras, halPhraseEvent->num_phrases);
52227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        // FIXME: transfer buffer ownership. should have a method for that in hidl_vec
52327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        phraseEvent->phraseExtras.resize(halPhraseEvent->num_phrases);
52427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        delete[] phraseExtras;
52527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        event = reinterpret_cast<ISoundTriggerHwCallback::RecognitionEvent *>(phraseEvent);
52627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    } else {
52727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        event = new ISoundTriggerHwCallback::RecognitionEvent();
52827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    }
52927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
53027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    event->status = static_cast<ISoundTriggerHwCallback::RecognitionStatus>(halEvent->status);
53127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    event->type = static_cast<SoundModelType>(halEvent->type);
53227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    // event->model to be remapped by called
53327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    event->captureAvailable = halEvent->capture_available;
53427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    event->captureSession = halEvent->capture_session;
53527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    event->captureDelayMs = halEvent->capture_delay_ms;
53627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    event->capturePreambleMs = halEvent->capture_preamble_ms;
53727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    event->triggerInData = halEvent->trigger_in_data;
53827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    event->audioConfig.sampleRateHz = halEvent->audio_config.sample_rate;
53927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    event->audioConfig.channelMask =
54027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent            (audio::common::V2_0::AudioChannelMask)halEvent->audio_config.channel_mask;
54127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    event->audioConfig.format = (audio::common::V2_0::AudioFormat)halEvent->audio_config.format;
54227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    event->data.setToExternal(
54327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent            const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(halEvent)) + halEvent->data_offset,
54427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent            halEvent->data_size);
54527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
54627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    return event;
54727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent}
54827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
54927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent// static
55027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurentvoid SoundTriggerHalImpl::convertPhraseRecognitionExtraFromHal(
55127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        PhraseRecognitionExtra *extra,
55227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        const struct sound_trigger_phrase_recognition_extra *halExtra)
55327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent{
55427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    extra->id = halExtra->id;
55527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    extra->recognitionModes = halExtra->recognition_modes;
55627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    extra->confidenceLevel = halExtra->confidence_level;
55727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
55827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    ConfidenceLevel *levels =
55927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent            new ConfidenceLevel[halExtra->num_levels];
56027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    for (unsigned int i = 0; i < halExtra->num_levels; i++) {
56127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        levels[i].userId = halExtra->levels[i].user_id;
56227ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent        levels[i].levelPercent = halExtra->levels[i].level;
56327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    }
56427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    extra->levels.setToExternal(levels, halExtra->num_levels);
56527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    // FIXME: transfer buffer ownership. should have a method for that in hidl_vec
56627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    extra->levels.resize(halExtra->num_levels);
56727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent    delete[] levels;
56827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent}
56927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
5703acaa668c102cf096a9e3bc540d7a74ca3ac5c36Mikhail NaganovISoundTriggerHw *HIDL_FETCH_ISoundTriggerHw(const char* /* name */)
57127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent{
5723acaa668c102cf096a9e3bc540d7a74ca3ac5c36Mikhail Naganov    return new SoundTriggerHalImpl();
57327ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent}
57427ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent} // namespace implementation
57527ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent}  // namespace V2_0
57627ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent}  // namespace soundtrigger
57727ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent}  // namespace hardware
57827ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent}  // namespace android
57927ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
58027ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
58127ef4d872d9f6bbbc62d03b807cae694a3c6e2e8Eric Laurent
582