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

Commit 3e4d2ed6 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "soundtrigger: Add support for HAL V2.1"

parents e2204b2b 6f9f1e2b
Loading
Loading
Loading
Loading
+5 −1
Original line number Original line Diff line number Diff line
@@ -49,11 +49,15 @@ LOCAL_SRC_FILES += \
LOCAL_SHARED_LIBRARIES += \
LOCAL_SHARED_LIBRARIES += \
    libhwbinder \
    libhwbinder \
    libhidlbase \
    libhidlbase \
    libhidlmemory \
    libhidltransport \
    libhidltransport \
    libbase \
    libbase \
    libaudiohal \
    libaudiohal \
    android.hardware.soundtrigger@2.0 \
    android.hardware.soundtrigger@2.0 \
    android.hardware.audio.common@2.0
    android.hardware.soundtrigger@2.1 \
    android.hardware.audio.common@2.0 \
    android.hidl.allocator@1.0 \
    android.hidl.memory@1.0
endif
endif




+277 −119
Original line number Original line Diff line number Diff line
@@ -17,17 +17,87 @@
#define LOG_TAG "SoundTriggerHalHidl"
#define LOG_TAG "SoundTriggerHalHidl"
//#define LOG_NDEBUG 0
//#define LOG_NDEBUG 0


#include <android/hidl/allocator/1.0/IAllocator.h>
#include <media/audiohal/hidl/HalDeathHandler.h>
#include <media/audiohal/hidl/HalDeathHandler.h>
#include <utils/Log.h>
#include <utils/Log.h>
#include "SoundTriggerHalHidl.h"
#include "SoundTriggerHalHidl.h"
#include <hidlmemory/mapping.h>
#include <hwbinder/IPCThreadState.h>
#include <hwbinder/IPCThreadState.h>
#include <hwbinder/ProcessState.h>
#include <hwbinder/ProcessState.h>


namespace android {
namespace android {


using android::hardware::Return;
using ::android::hardware::ProcessState;
using android::hardware::ProcessState;
using ::android::hardware::Return;
using android::hardware::audio::common::V2_0::AudioDevice;
using ::android::hardware::Status;
using ::android::hardware::Void;
using ::android::hardware::audio::common::V2_0::AudioDevice;
using ::android::hardware::hidl_memory;
using ::android::hidl::allocator::V1_0::IAllocator;
using ::android::hidl::memory::V1_0::IMemory;

namespace {

// Backs up by the vector with the contents of shared memory.
// It is assumed that the passed hidl_vector is empty, so it's
// not cleared if the memory is a null object.
// The caller needs to keep the returned sp<IMemory> as long as
// the data is needed.
std::pair<bool, sp<IMemory>> memoryAsVector(const hidl_memory& m, hidl_vec<uint8_t>* vec) {
    sp<IMemory> memory;
    if (m.size() == 0) {
        return std::make_pair(true, memory);
    }
    memory = mapMemory(m);
    if (memory != nullptr) {
        memory->read();
        vec->setToExternal(static_cast<uint8_t*>(static_cast<void*>(memory->getPointer())),
                memory->getSize());
        return std::make_pair(true, memory);
    }
    ALOGE("%s: Could not map HIDL memory to IMemory", __func__);
    return std::make_pair(false, memory);
}

// Moves the data from the vector into allocated shared memory,
// emptying the vector.
// It is assumed that the passed hidl_memory is a null object, so it's
// not reset if the vector is empty.
// The caller needs to keep the returned sp<IMemory> as long as
// the data is needed.
std::pair<bool, sp<IMemory>> moveVectorToMemory(hidl_vec<uint8_t>* v, hidl_memory* mem) {
    sp<IMemory> memory;
    if (v->size() == 0) {
        return std::make_pair(true, memory);
    }
    sp<IAllocator> ashmem = IAllocator::getService("ashmem");
    if (ashmem == 0) {
        ALOGE("Failed to retrieve ashmem allocator service");
        return std::make_pair(false, memory);
    }
    bool success = false;
    Return<void> r = ashmem->allocate(v->size(), [&](bool s, const hidl_memory& m) {
        success = s;
        if (success) *mem = m;
    });
    if (r.isOk() && success) {
        memory = hardware::mapMemory(*mem);
        if (memory != 0) {
            memory->update();
            memcpy(memory->getPointer(), v->data(), v->size());
            memory->commit();
            v->resize(0);
            return std::make_pair(true, memory);
        } else {
            ALOGE("Failed to map allocated ashmem");
        }
    } else {
        ALOGE("Failed to allocate %llu bytes from ashmem", (unsigned long long)v->size());
    }
    return std::make_pair(false, memory);
}

}  // namespace


/* static */
/* static */
sp<SoundTriggerHalInterface> SoundTriggerHalInterface::connectModule(const char *moduleName)
sp<SoundTriggerHalInterface> SoundTriggerHalInterface::connectModule(const char *moduleName)
@@ -94,35 +164,61 @@ int SoundTriggerHalHidl::loadSoundModel(struct sound_trigger_sound_model *sound_
                        "loadSoundModel(): wrap around in sound model IDs, num loaded models %zd",
                        "loadSoundModel(): wrap around in sound model IDs, num loaded models %zd",
                        mSoundModels.size());
                        mSoundModels.size());


    ISoundTriggerHw::SoundModel *halSoundModel =
            convertSoundModelToHal(sound_model);
    if (halSoundModel == NULL) {
        return -EINVAL;
    }

    Return<void> hidlReturn;
    Return<void> hidlReturn;
    int ret;
    int ret;
    SoundModelHandle halHandle;
    SoundModelHandle halHandle;
    {
    sp<V2_1_ISoundTriggerHw> soundtrigger_2_1 = toService2_1(soundtrigger);
        AutoMutex lock(mHalLock);
    if (sound_model->type == SOUND_MODEL_TYPE_KEYPHRASE) {
    if (sound_model->type == SOUND_MODEL_TYPE_KEYPHRASE) {
        if (!soundtrigger_2_1) {
            ISoundTriggerHw::PhraseSoundModel halSoundModel;
            convertPhraseSoundModelToHal(&halSoundModel, sound_model);
            AutoMutex lock(mHalLock);
            hidlReturn = soundtrigger->loadPhraseSoundModel(
            hidlReturn = soundtrigger->loadPhraseSoundModel(
                    *(const ISoundTriggerHw::PhraseSoundModel *)halSoundModel,
                    halSoundModel,
                    this, modelId, [&](int32_t retval, auto res) {
                    this, modelId, [&](int32_t retval, auto res) {
                        ret = retval;
                        ret = retval;
                        halHandle = res;
                        halHandle = res;
                    });
                    });

        } else {
        } else {
            hidlReturn = soundtrigger->loadSoundModel(*halSoundModel,
            V2_1_ISoundTriggerHw::PhraseSoundModel halSoundModel;
            auto result = convertPhraseSoundModelToHal(&halSoundModel, sound_model);
            if (result.first) {
                AutoMutex lock(mHalLock);
                hidlReturn = soundtrigger_2_1->loadPhraseSoundModel_2_1(
                        halSoundModel,
                        this, modelId, [&](int32_t retval, auto res) {
                        this, modelId, [&](int32_t retval, auto res) {
                            ret = retval;
                            ret = retval;
                            halHandle = res;
                            halHandle = res;
                        });
                        });
            } else {
                return NO_MEMORY;
            }
        }
    } else {
        if (!soundtrigger_2_1) {
            ISoundTriggerHw::SoundModel halSoundModel;
            convertSoundModelToHal(&halSoundModel, sound_model);
            AutoMutex lock(mHalLock);
            hidlReturn = soundtrigger->loadSoundModel(halSoundModel,
                    this, modelId, [&](int32_t retval, auto res) {
                        ret = retval;
                        halHandle = res;
                    });
        } else {
            V2_1_ISoundTriggerHw::SoundModel halSoundModel;
            auto result = convertSoundModelToHal(&halSoundModel, sound_model);
            if (result.first) {
                AutoMutex lock(mHalLock);
                hidlReturn = soundtrigger_2_1->loadSoundModel_2_1(halSoundModel,
                        this, modelId, [&](int32_t retval, auto res) {
                            ret = retval;
                            halHandle = res;
                        });
            } else {
                return NO_MEMORY;
            }
        }
        }
    }
    }

    delete halSoundModel;


    if (hidlReturn.isOk()) {
    if (hidlReturn.isOk()) {
        if (ret == 0) {
        if (ret == 0) {
@@ -185,16 +281,27 @@ int SoundTriggerHalHidl::startRecognition(sound_model_handle_t handle,
    model->mRecognitionCallback = callback;
    model->mRecognitionCallback = callback;
    model->mRecognitionCookie = cookie;
    model->mRecognitionCookie = cookie;


    ISoundTriggerHw::RecognitionConfig *halConfig =
    sp<V2_1_ISoundTriggerHw> soundtrigger_2_1 = toService2_1(soundtrigger);
            convertRecognitionConfigToHal(config);

    Return<int32_t> hidlReturn(0);
    Return<int32_t> hidlReturn(0);

    if (!soundtrigger_2_1) {
        ISoundTriggerHw::RecognitionConfig halConfig;
        convertRecognitionConfigToHal(&halConfig, config);
        {
        {
            AutoMutex lock(mHalLock);
            AutoMutex lock(mHalLock);
        hidlReturn = soundtrigger->startRecognition(model->mHalHandle, *halConfig, this, handle);
            hidlReturn = soundtrigger->startRecognition(model->mHalHandle, halConfig, this, handle);
        }
    } else {
        V2_1_ISoundTriggerHw::RecognitionConfig halConfig;
        auto result = convertRecognitionConfigToHal(&halConfig, config);
        if (result.first) {
            AutoMutex lock(mHalLock);
            hidlReturn = soundtrigger_2_1->startRecognition_2_1(
                    model->mHalHandle, halConfig, this, handle);
        } else {
            return NO_MEMORY;
        }
    }
    }

    delete halConfig;


    if (!hidlReturn.isOk()) {
    if (!hidlReturn.isOk()) {
        ALOGE("startRecognition error %s", hidlReturn.description().c_str());
        ALOGE("startRecognition error %s", hidlReturn.description().c_str());
@@ -275,6 +382,12 @@ sp<ISoundTriggerHw> SoundTriggerHalHidl::getService()
    return mISoundTrigger;
    return mISoundTrigger;
}
}


sp<V2_1_ISoundTriggerHw> SoundTriggerHalHidl::toService2_1(const sp<ISoundTriggerHw>& s)
{
    auto castResult_2_1 = V2_1_ISoundTriggerHw::castFrom(s);
    return castResult_2_1.isOk() ? static_cast<sp<V2_1_ISoundTriggerHw>>(castResult_2_1) : nullptr;
}

sp<SoundTriggerHalHidl::SoundModel> SoundTriggerHalHidl::getModel(sound_model_handle_t handle)
sp<SoundTriggerHalHidl::SoundModel> SoundTriggerHalHidl::getModel(sound_model_handle_t handle)
{
{
    AutoMutex lock(mLock);
    AutoMutex lock(mLock);
@@ -347,40 +460,52 @@ void SoundTriggerHalHidl::convertTriggerPhraseToHal(
    halTriggerPhrase->text = triggerPhrase->text;
    halTriggerPhrase->text = triggerPhrase->text;
}
}


ISoundTriggerHw::SoundModel *SoundTriggerHalHidl::convertSoundModelToHal(
        const struct sound_trigger_sound_model *soundModel)
{
    ISoundTriggerHw::SoundModel *halModel = NULL;
    if (soundModel->type == SOUND_MODEL_TYPE_KEYPHRASE) {
        ISoundTriggerHw::PhraseSoundModel *halKeyPhraseModel =
                new ISoundTriggerHw::PhraseSoundModel();
        struct sound_trigger_phrase_sound_model *keyPhraseModel =
                (struct sound_trigger_phrase_sound_model *)soundModel;
        ISoundTriggerHw::Phrase *halPhrases =
                new ISoundTriggerHw::Phrase[keyPhraseModel->num_phrases];



void SoundTriggerHalHidl::convertTriggerPhrasesToHal(
        hidl_vec<ISoundTriggerHw::Phrase> *halTriggerPhrases,
        struct sound_trigger_phrase_sound_model *keyPhraseModel)
{
    halTriggerPhrases->resize(keyPhraseModel->num_phrases);
    for (unsigned int i = 0; i < keyPhraseModel->num_phrases; i++) {
    for (unsigned int i = 0; i < keyPhraseModel->num_phrases; i++) {
            convertTriggerPhraseToHal(&halPhrases[i],
        convertTriggerPhraseToHal(&(*halTriggerPhrases)[i], &keyPhraseModel->phrases[i]);
                                      &keyPhraseModel->phrases[i]);
    }
    }
        halKeyPhraseModel->phrases.setToExternal(halPhrases, keyPhraseModel->num_phrases);
        // FIXME: transfer buffer ownership. should have a method for that in hidl_vec
        halKeyPhraseModel->phrases.resize(keyPhraseModel->num_phrases);

        delete[] halPhrases;

        halModel = (ISoundTriggerHw::SoundModel *)halKeyPhraseModel;
    } else {
        halModel = new ISoundTriggerHw::SoundModel();
}
}

void SoundTriggerHalHidl::convertSoundModelToHal(ISoundTriggerHw::SoundModel *halModel,
        const struct sound_trigger_sound_model *soundModel)
{
    halModel->type = (SoundModelType)soundModel->type;
    halModel->type = (SoundModelType)soundModel->type;
    convertUuidToHal(&halModel->uuid, &soundModel->uuid);
    convertUuidToHal(&halModel->uuid, &soundModel->uuid);
    convertUuidToHal(&halModel->vendorUuid, &soundModel->vendor_uuid);
    convertUuidToHal(&halModel->vendorUuid, &soundModel->vendor_uuid);
    halModel->data.setToExternal((uint8_t *)soundModel + soundModel->data_offset, soundModel->data_size);
    halModel->data.setToExternal((uint8_t *)soundModel + soundModel->data_offset, soundModel->data_size);
    halModel->data.resize(soundModel->data_size);
}


    return halModel;
std::pair<bool, sp<IMemory>> SoundTriggerHalHidl::convertSoundModelToHal(
        V2_1_ISoundTriggerHw::SoundModel *halModel,
        const struct sound_trigger_sound_model *soundModel)
{
    convertSoundModelToHal(&halModel->header, soundModel);
    return moveVectorToMemory(&halModel->header.data, &halModel->data);
}

void SoundTriggerHalHidl::convertPhraseSoundModelToHal(
        ISoundTriggerHw::PhraseSoundModel *halKeyPhraseModel,
        const struct sound_trigger_sound_model *soundModel)
{
    struct sound_trigger_phrase_sound_model *keyPhraseModel =
            (struct sound_trigger_phrase_sound_model *)soundModel;
    convertTriggerPhrasesToHal(&halKeyPhraseModel->phrases, keyPhraseModel);
    convertSoundModelToHal(&halKeyPhraseModel->common, soundModel);
}

std::pair<bool, sp<IMemory>> SoundTriggerHalHidl::convertPhraseSoundModelToHal(
        V2_1_ISoundTriggerHw::PhraseSoundModel *halKeyPhraseModel,
        const struct sound_trigger_sound_model *soundModel)
{
    struct sound_trigger_phrase_sound_model *keyPhraseModel =
            (struct sound_trigger_phrase_sound_model *)soundModel;
    convertTriggerPhrasesToHal(&halKeyPhraseModel->phrases, keyPhraseModel);
    return convertSoundModelToHal(&halKeyPhraseModel->common, soundModel);
}
}


void SoundTriggerHalHidl::convertPhraseRecognitionExtraToHal(
void SoundTriggerHalHidl::convertPhraseRecognitionExtraToHal(
@@ -390,52 +515,42 @@ void SoundTriggerHalHidl::convertPhraseRecognitionExtraToHal(
    halExtra->id = extra->id;
    halExtra->id = extra->id;
    halExtra->recognitionModes = extra->recognition_modes;
    halExtra->recognitionModes = extra->recognition_modes;
    halExtra->confidenceLevel = extra->confidence_level;
    halExtra->confidenceLevel = extra->confidence_level;
    ConfidenceLevel *halLevels =
    halExtra->levels.resize(extra->num_levels);
            new ConfidenceLevel[extra->num_levels];
    for (unsigned int i = 0; i < extra->num_levels; i++) {
    for (unsigned int i = 0; i < extra->num_levels; i++) {
        halLevels[i].userId = extra->levels[i].user_id;
        halExtra->levels[i].userId = extra->levels[i].user_id;
        halLevels[i].levelPercent = extra->levels[i].level;
        halExtra->levels[i].levelPercent = extra->levels[i].level;
    }
    }
    halExtra->levels.setToExternal(halLevels, extra->num_levels);
    // FIXME: transfer buffer ownership. should have a method for that in hidl_vec
    halExtra->levels.resize(extra->num_levels);

    delete[] halLevels;
}
}



void SoundTriggerHalHidl::convertRecognitionConfigToHal(
ISoundTriggerHw::RecognitionConfig *SoundTriggerHalHidl::convertRecognitionConfigToHal(
        ISoundTriggerHw::RecognitionConfig *halConfig,
        const struct sound_trigger_recognition_config *config)
        const struct sound_trigger_recognition_config *config)
{
{
    ISoundTriggerHw::RecognitionConfig *halConfig =
            new ISoundTriggerHw::RecognitionConfig();

    halConfig->captureHandle = config->capture_handle;
    halConfig->captureHandle = config->capture_handle;
    halConfig->captureDevice = (AudioDevice)config->capture_device;
    halConfig->captureDevice = (AudioDevice)config->capture_device;
    halConfig->captureRequested = (uint32_t)config->capture_requested;
    halConfig->captureRequested = (uint32_t)config->capture_requested;


    PhraseRecognitionExtra *halExtras =
    halConfig->phrases.resize(config->num_phrases);
            new PhraseRecognitionExtra[config->num_phrases];

    for (unsigned int i = 0; i < config->num_phrases; i++) {
    for (unsigned int i = 0; i < config->num_phrases; i++) {
        convertPhraseRecognitionExtraToHal(&halExtras[i],
        convertPhraseRecognitionExtraToHal(&halConfig->phrases[i],
                                  &config->phrases[i]);
                                  &config->phrases[i]);
    }
    }
    halConfig->phrases.setToExternal(halExtras, config->num_phrases);
    // FIXME: transfer buffer ownership. should have a method for that in hidl_vec
    halConfig->phrases.resize(config->num_phrases);

    delete[] halExtras;


    halConfig->data.setToExternal((uint8_t *)config + config->data_offset, config->data_size);
    halConfig->data.setToExternal((uint8_t *)config + config->data_offset, config->data_size);
}


    return halConfig;
std::pair<bool, sp<IMemory>> SoundTriggerHalHidl::convertRecognitionConfigToHal(
        V2_1_ISoundTriggerHw::RecognitionConfig *halConfig,
        const struct sound_trigger_recognition_config *config)
{
    convertRecognitionConfigToHal(&halConfig->header, config);
    return moveVectorToMemory(&halConfig->header.data, &halConfig->data);
}
}




// ISoundTriggerHwCallback
// ISoundTriggerHwCallback
::android::hardware::Return<void> SoundTriggerHalHidl::recognitionCallback(
::android::hardware::Return<void> SoundTriggerHalHidl::recognitionCallback(
        const ISoundTriggerHwCallback::RecognitionEvent& halEvent,
        const V2_0_ISoundTriggerHwCallback::RecognitionEvent& halEvent,
        CallbackCookie cookie)
        CallbackCookie cookie)
{
{
    sp<SoundModel> model;
    sp<SoundModel> model;
@@ -459,7 +574,7 @@ ISoundTriggerHw::RecognitionConfig *SoundTriggerHalHidl::convertRecognitionConfi
}
}


::android::hardware::Return<void> SoundTriggerHalHidl::phraseRecognitionCallback(
::android::hardware::Return<void> SoundTriggerHalHidl::phraseRecognitionCallback(
        const ISoundTriggerHwCallback::PhraseRecognitionEvent& halEvent,
        const V2_0_ISoundTriggerHwCallback::PhraseRecognitionEvent& halEvent,
        CallbackCookie cookie)
        CallbackCookie cookie)
{
{
    sp<SoundModel> model;
    sp<SoundModel> model;
@@ -471,14 +586,13 @@ ISoundTriggerHw::RecognitionConfig *SoundTriggerHalHidl::convertRecognitionConfi
        }
        }
    }
    }


    struct sound_trigger_recognition_event *event = convertRecognitionEventFromHal(
    struct sound_trigger_phrase_recognition_event *event =
                                   (const ISoundTriggerHwCallback::RecognitionEvent *)&halEvent);
            convertPhraseRecognitionEventFromHal(&halEvent);
    if (event == NULL) {
    if (event == NULL) {
        return Return<void>();
        return Return<void>();
    }
    }

    event->common.model = model->mHandle;
    event->model = model->mHandle;
    model->mRecognitionCallback(&event->common, model->mRecognitionCookie);
    model->mRecognitionCallback(event, model->mRecognitionCookie);


    free(event);
    free(event);


@@ -486,7 +600,7 @@ ISoundTriggerHw::RecognitionConfig *SoundTriggerHalHidl::convertRecognitionConfi
}
}


::android::hardware::Return<void> SoundTriggerHalHidl::soundModelCallback(
::android::hardware::Return<void> SoundTriggerHalHidl::soundModelCallback(
        const ISoundTriggerHwCallback::ModelEvent& halEvent,
        const V2_0_ISoundTriggerHwCallback::ModelEvent& halEvent,
        CallbackCookie cookie)
        CallbackCookie cookie)
{
{
    sp<SoundModel> model;
    sp<SoundModel> model;
@@ -511,9 +625,37 @@ ISoundTriggerHw::RecognitionConfig *SoundTriggerHalHidl::convertRecognitionConfi
    return Return<void>();
    return Return<void>();
}
}


::android::hardware::Return<void> SoundTriggerHalHidl::recognitionCallback_2_1(
        const ISoundTriggerHwCallback::RecognitionEvent& event, CallbackCookie cookie) {
    // The data vector in the 'header' part of V2.1 structure is empty, thus copying is cheap.
    V2_0_ISoundTriggerHwCallback::RecognitionEvent event_2_0 = event.header;
    auto result = memoryAsVector(event.data, &event_2_0.data);
    return result.first ? recognitionCallback(event_2_0, cookie) : Void();
}

::android::hardware::Return<void> SoundTriggerHalHidl::phraseRecognitionCallback_2_1(
        const ISoundTriggerHwCallback::PhraseRecognitionEvent& event, int32_t cookie) {
    V2_0_ISoundTriggerHwCallback::PhraseRecognitionEvent event_2_0;
    // The data vector in the 'header' part of V2.1 structure is empty, thus copying is cheap.
    event_2_0.common = event.common.header;
    event_2_0.phraseExtras.setToExternal(
            const_cast<PhraseRecognitionExtra*>(event.phraseExtras.data()),
            event.phraseExtras.size());
    auto result = memoryAsVector(event.common.data, &event_2_0.common.data);
    return result.first ? phraseRecognitionCallback(event_2_0, cookie) : Void();
}

::android::hardware::Return<void> SoundTriggerHalHidl::soundModelCallback_2_1(
        const ISoundTriggerHwCallback::ModelEvent& event, CallbackCookie cookie) {
    // The data vector in the 'header' part of V2.1 structure is empty, thus copying is cheap.
    V2_0_ISoundTriggerHwCallback::ModelEvent event_2_0 = event.header;
    auto result = memoryAsVector(event.data, &event_2_0.data);
    return result.first ? soundModelCallback(event_2_0, cookie) : Void();
}



struct sound_trigger_model_event *SoundTriggerHalHidl::convertSoundModelEventFromHal(
struct sound_trigger_model_event *SoundTriggerHalHidl::convertSoundModelEventFromHal(
                                              const ISoundTriggerHwCallback::ModelEvent *halEvent)
                                              const V2_0_ISoundTriggerHwCallback::ModelEvent *halEvent)
{
{
    struct sound_trigger_model_event *event = (struct sound_trigger_model_event *)malloc(
    struct sound_trigger_model_event *event = (struct sound_trigger_model_event *)malloc(
            sizeof(struct sound_trigger_model_event) +
            sizeof(struct sound_trigger_model_event) +
@@ -550,37 +692,55 @@ void SoundTriggerHalHidl::convertPhraseRecognitionExtraFromHal(
}
}




struct sound_trigger_recognition_event *SoundTriggerHalHidl::convertRecognitionEventFromHal(
struct sound_trigger_phrase_recognition_event* SoundTriggerHalHidl::convertPhraseRecognitionEventFromHal(
        const ISoundTriggerHwCallback::RecognitionEvent *halEvent)
        const V2_0_ISoundTriggerHwCallback::PhraseRecognitionEvent *halPhraseEvent)
{
{
    struct sound_trigger_recognition_event *event;
    if (halPhraseEvent->common.type != SoundModelType::KEYPHRASE) {

        ALOGE("Received non-keyphrase event type as PhraseRecognitionEvent");
    if (halEvent->type == SoundModelType::KEYPHRASE) {
        return NULL;
    }
    struct sound_trigger_phrase_recognition_event *phraseEvent =
    struct sound_trigger_phrase_recognition_event *phraseEvent =
            (struct sound_trigger_phrase_recognition_event *)malloc(
            (struct sound_trigger_phrase_recognition_event *)malloc(
                    sizeof(struct sound_trigger_phrase_recognition_event) +
                    sizeof(struct sound_trigger_phrase_recognition_event) +
                        halEvent->data.size());
                    halPhraseEvent->common.data.size());
    if (phraseEvent == NULL) {
    if (phraseEvent == NULL) {
        return NULL;
        return NULL;
    }
    }
        const ISoundTriggerHwCallback::PhraseRecognitionEvent *halPhraseEvent =
    phraseEvent->common.data_offset = sizeof(sound_trigger_phrase_recognition_event);
                (const ISoundTriggerHwCallback::PhraseRecognitionEvent *)halEvent;


    for (unsigned int i = 0; i < halPhraseEvent->phraseExtras.size(); i++) {
    for (unsigned int i = 0; i < halPhraseEvent->phraseExtras.size(); i++) {
        convertPhraseRecognitionExtraFromHal(&phraseEvent->phrase_extras[i],
        convertPhraseRecognitionExtraFromHal(&phraseEvent->phrase_extras[i],
                                             &halPhraseEvent->phraseExtras[i]);
                                             &halPhraseEvent->phraseExtras[i]);
    }
    }
    phraseEvent->num_phrases = halPhraseEvent->phraseExtras.size();
    phraseEvent->num_phrases = halPhraseEvent->phraseExtras.size();
        event = (struct sound_trigger_recognition_event *)phraseEvent;

        event->data_offset = sizeof(sound_trigger_phrase_recognition_event);
    fillRecognitionEventFromHal(&phraseEvent->common, &halPhraseEvent->common);
    } else {
    return phraseEvent;
}

struct sound_trigger_recognition_event *SoundTriggerHalHidl::convertRecognitionEventFromHal(
        const V2_0_ISoundTriggerHwCallback::RecognitionEvent *halEvent)
{
    if (halEvent->type == SoundModelType::KEYPHRASE) {
        ALOGE("Received keyphrase event type as RecognitionEvent");
        return NULL;
    }
    struct sound_trigger_recognition_event *event;
    event = (struct sound_trigger_recognition_event *)malloc(
    event = (struct sound_trigger_recognition_event *)malloc(
            sizeof(struct sound_trigger_recognition_event) + halEvent->data.size());
            sizeof(struct sound_trigger_recognition_event) + halEvent->data.size());
    if (event == NULL) {
    if (event == NULL) {
        return NULL;
        return NULL;
    }
    }
    event->data_offset = sizeof(sound_trigger_recognition_event);
    event->data_offset = sizeof(sound_trigger_recognition_event);

    fillRecognitionEventFromHal(event, halEvent);
    return event;
}
}

void SoundTriggerHalHidl::fillRecognitionEventFromHal(
        struct sound_trigger_recognition_event *event,
        const V2_0_ISoundTriggerHwCallback::RecognitionEvent *halEvent)
{
    event->status = (int)halEvent->status;
    event->status = (int)halEvent->status;
    event->type = (sound_trigger_sound_model_type_t)halEvent->type;
    event->type = (sound_trigger_sound_model_type_t)halEvent->type;
    // event->model to be set by caller
    // event->model to be set by caller
@@ -597,8 +757,6 @@ struct sound_trigger_recognition_event *SoundTriggerHalHidl::convertRecognitionE
    uint8_t *dst = (uint8_t *)event + event->data_offset;
    uint8_t *dst = (uint8_t *)event + event->data_offset;
    uint8_t *src = (uint8_t *)&halEvent->data[0];
    uint8_t *src = (uint8_t *)&halEvent->data[0];
    memcpy(dst, src, halEvent->data.size());
    memcpy(dst, src, halEvent->data.size());

    return event;
}
}


} // namespace android
} // namespace android