Loading services/soundtrigger/Android.mk +5 −1 Original line number Original line Diff line number Diff line Loading @@ -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 Loading services/soundtrigger/SoundTriggerHalHidl.cpp +277 −119 Original line number Original line Diff line number Diff line Loading @@ -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) Loading Loading @@ -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) { Loading Loading @@ -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()); Loading Loading @@ -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); Loading Loading @@ -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( Loading @@ -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; Loading @@ -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; Loading @@ -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); Loading @@ -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; Loading @@ -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) + Loading Loading @@ -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 Loading @@ -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 Loading
services/soundtrigger/Android.mk +5 −1 Original line number Original line Diff line number Diff line Loading @@ -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 Loading
services/soundtrigger/SoundTriggerHalHidl.cpp +277 −119 Original line number Original line Diff line number Diff line Loading @@ -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) Loading Loading @@ -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) { Loading Loading @@ -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()); Loading Loading @@ -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); Loading Loading @@ -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( Loading @@ -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; Loading @@ -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; Loading @@ -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); Loading @@ -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; Loading @@ -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) + Loading Loading @@ -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 Loading @@ -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