• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "SoundTriggerHalHidl"
18 //#define LOG_NDEBUG 0
19 
20 #include <android/hidl/allocator/1.0/IAllocator.h>
21 #include <media/audiohal/hidl/HalDeathHandler.h>
22 #include <utils/Log.h>
23 #include "SoundTriggerHalHidl.h"
24 #include <hidlmemory/mapping.h>
25 #include <hwbinder/IPCThreadState.h>
26 #include <hwbinder/ProcessState.h>
27 
28 namespace android {
29 
30 using ::android::hardware::ProcessState;
31 using ::android::hardware::Return;
32 using ::android::hardware::Status;
33 using ::android::hardware::Void;
34 using ::android::hardware::audio::common::V2_0::AudioDevice;
35 using ::android::hardware::hidl_memory;
36 using ::android::hidl::allocator::V1_0::IAllocator;
37 using ::android::hidl::memory::V1_0::IMemory;
38 
39 namespace {
40 
41 // Backs up by the vector with the contents of shared memory.
42 // It is assumed that the passed hidl_vector is empty, so it's
43 // not cleared if the memory is a null object.
44 // The caller needs to keep the returned sp<IMemory> as long as
45 // the data is needed.
memoryAsVector(const hidl_memory & m,hidl_vec<uint8_t> * vec)46 std::pair<bool, sp<IMemory>> memoryAsVector(const hidl_memory& m, hidl_vec<uint8_t>* vec) {
47     sp<IMemory> memory;
48     if (m.size() == 0) {
49         return std::make_pair(true, memory);
50     }
51     memory = mapMemory(m);
52     if (memory != nullptr) {
53         memory->read();
54         vec->setToExternal(static_cast<uint8_t*>(static_cast<void*>(memory->getPointer())),
55                 memory->getSize());
56         return std::make_pair(true, memory);
57     }
58     ALOGE("%s: Could not map HIDL memory to IMemory", __func__);
59     return std::make_pair(false, memory);
60 }
61 
62 // Moves the data from the vector into allocated shared memory,
63 // emptying the vector.
64 // It is assumed that the passed hidl_memory is a null object, so it's
65 // not reset if the vector is empty.
66 // The caller needs to keep the returned sp<IMemory> as long as
67 // the data is needed.
moveVectorToMemory(hidl_vec<uint8_t> * v,hidl_memory * mem)68 std::pair<bool, sp<IMemory>> moveVectorToMemory(hidl_vec<uint8_t>* v, hidl_memory* mem) {
69     sp<IMemory> memory;
70     if (v->size() == 0) {
71         return std::make_pair(true, memory);
72     }
73     sp<IAllocator> ashmem = IAllocator::getService("ashmem");
74     if (ashmem == 0) {
75         ALOGE("Failed to retrieve ashmem allocator service");
76         return std::make_pair(false, memory);
77     }
78     bool success = false;
79     Return<void> r = ashmem->allocate(v->size(), [&](bool s, const hidl_memory& m) {
80         success = s;
81         if (success) *mem = m;
82     });
83     if (r.isOk() && success) {
84         memory = hardware::mapMemory(*mem);
85         if (memory != 0) {
86             memory->update();
87             memcpy(memory->getPointer(), v->data(), v->size());
88             memory->commit();
89             v->resize(0);
90             return std::make_pair(true, memory);
91         } else {
92             ALOGE("Failed to map allocated ashmem");
93         }
94     } else {
95         ALOGE("Failed to allocate %llu bytes from ashmem", (unsigned long long)v->size());
96     }
97     return std::make_pair(false, memory);
98 }
99 
100 }  // namespace
101 
102 /* static */
connectModule(const char * moduleName)103 sp<SoundTriggerHalInterface> SoundTriggerHalInterface::connectModule(const char *moduleName)
104 {
105     return new SoundTriggerHalHidl(moduleName);
106 }
107 
getProperties(struct sound_trigger_properties * properties)108 int SoundTriggerHalHidl::getProperties(struct sound_trigger_properties *properties)
109 {
110     sp<ISoundTriggerHw> soundtrigger = getService();
111     if (soundtrigger == 0) {
112         return -ENODEV;
113     }
114 
115     ISoundTriggerHw::Properties halProperties;
116     Return<void> hidlReturn;
117     int ret;
118     {
119         AutoMutex lock(mHalLock);
120         hidlReturn = soundtrigger->getProperties([&](int rc, auto res) {
121             ret = rc;
122             halProperties = res;
123             ALOGI("getProperties res implementor %s", res.implementor.c_str());
124         });
125     }
126 
127     if (hidlReturn.isOk()) {
128         if (ret == 0) {
129             convertPropertiesFromHal(properties, &halProperties);
130         }
131     } else {
132         ALOGE("getProperties error %s", hidlReturn.description().c_str());
133         return FAILED_TRANSACTION;
134     }
135     ALOGI("getProperties ret %d", ret);
136     return ret;
137 }
138 
loadSoundModel(struct sound_trigger_sound_model * sound_model,sound_model_callback_t callback,void * cookie,sound_model_handle_t * handle)139 int SoundTriggerHalHidl::loadSoundModel(struct sound_trigger_sound_model *sound_model,
140                         sound_model_callback_t callback,
141                         void *cookie,
142                         sound_model_handle_t *handle)
143 {
144     if (handle == NULL) {
145         return -EINVAL;
146     }
147 
148     sp<ISoundTriggerHw> soundtrigger = getService();
149     if (soundtrigger == 0) {
150         return -ENODEV;
151     }
152 
153     uint32_t modelId;
154     {
155         AutoMutex lock(mLock);
156         do {
157             modelId = nextUniqueId();
158             ALOGI("loadSoundModel modelId %u", modelId);
159             sp<SoundModel> model = mSoundModels.valueFor(modelId);
160             ALOGI("loadSoundModel model %p", model.get());
161         } while (mSoundModels.valueFor(modelId) != 0 && modelId != 0);
162     }
163     LOG_ALWAYS_FATAL_IF(modelId == 0,
164                         "loadSoundModel(): wrap around in sound model IDs, num loaded models %zd",
165                         mSoundModels.size());
166 
167     Return<void> hidlReturn;
168     int ret;
169     SoundModelHandle halHandle;
170     sp<V2_1_ISoundTriggerHw> soundtrigger_2_1 = toService2_1(soundtrigger);
171     if (sound_model->type == SOUND_MODEL_TYPE_KEYPHRASE) {
172         if (!soundtrigger_2_1) {
173             ISoundTriggerHw::PhraseSoundModel halSoundModel;
174             convertPhraseSoundModelToHal(&halSoundModel, sound_model);
175             AutoMutex lock(mHalLock);
176             hidlReturn = soundtrigger->loadPhraseSoundModel(
177                     halSoundModel,
178                     this, modelId, [&](int32_t retval, auto res) {
179                         ret = retval;
180                         halHandle = res;
181                     });
182         } else {
183             V2_1_ISoundTriggerHw::PhraseSoundModel halSoundModel;
184             auto result = convertPhraseSoundModelToHal(&halSoundModel, sound_model);
185             if (result.first) {
186                 AutoMutex lock(mHalLock);
187                 hidlReturn = soundtrigger_2_1->loadPhraseSoundModel_2_1(
188                         halSoundModel,
189                         this, modelId, [&](int32_t retval, auto res) {
190                             ret = retval;
191                             halHandle = res;
192                         });
193             } else {
194                 return NO_MEMORY;
195             }
196         }
197     } else {
198         if (!soundtrigger_2_1) {
199             ISoundTriggerHw::SoundModel halSoundModel;
200             convertSoundModelToHal(&halSoundModel, sound_model);
201             AutoMutex lock(mHalLock);
202             hidlReturn = soundtrigger->loadSoundModel(halSoundModel,
203                     this, modelId, [&](int32_t retval, auto res) {
204                         ret = retval;
205                         halHandle = res;
206                     });
207         } else {
208             V2_1_ISoundTriggerHw::SoundModel halSoundModel;
209             auto result = convertSoundModelToHal(&halSoundModel, sound_model);
210             if (result.first) {
211                 AutoMutex lock(mHalLock);
212                 hidlReturn = soundtrigger_2_1->loadSoundModel_2_1(halSoundModel,
213                         this, modelId, [&](int32_t retval, auto res) {
214                             ret = retval;
215                             halHandle = res;
216                         });
217             } else {
218                 return NO_MEMORY;
219             }
220         }
221     }
222 
223     if (hidlReturn.isOk()) {
224         if (ret == 0) {
225             AutoMutex lock(mLock);
226             *handle = (sound_model_handle_t)modelId;
227             sp<SoundModel> model = new SoundModel(*handle, callback, cookie, halHandle);
228             mSoundModels.add(*handle, model);
229         }
230     } else {
231         ALOGE("loadSoundModel error %s", hidlReturn.description().c_str());
232         return FAILED_TRANSACTION;
233     }
234 
235     return ret;
236 }
237 
unloadSoundModel(sound_model_handle_t handle)238 int SoundTriggerHalHidl::unloadSoundModel(sound_model_handle_t handle)
239 {
240     sp<ISoundTriggerHw> soundtrigger = getService();
241     if (soundtrigger == 0) {
242         return -ENODEV;
243     }
244 
245     sp<SoundModel> model = removeModel(handle);
246     if (model == 0) {
247         ALOGE("unloadSoundModel model not found for handle %u", handle);
248         return -EINVAL;
249     }
250 
251     Return<int32_t> hidlReturn(0);
252     {
253         AutoMutex lock(mHalLock);
254         hidlReturn = soundtrigger->unloadSoundModel(model->mHalHandle);
255     }
256 
257     if (!hidlReturn.isOk()) {
258         ALOGE("unloadSoundModel error %s", hidlReturn.description().c_str());
259         return FAILED_TRANSACTION;
260     }
261 
262     return hidlReturn;
263 }
264 
startRecognition(sound_model_handle_t handle,const struct sound_trigger_recognition_config * config,recognition_callback_t callback,void * cookie)265 int SoundTriggerHalHidl::startRecognition(sound_model_handle_t handle,
266                          const struct sound_trigger_recognition_config *config,
267                          recognition_callback_t callback,
268                          void *cookie)
269 {
270     sp<ISoundTriggerHw> soundtrigger = getService();
271     if (soundtrigger == 0) {
272         return -ENODEV;
273     }
274 
275     sp<SoundModel> model = getModel(handle);
276     if (model == 0) {
277         ALOGE("startRecognition model not found for handle %u", handle);
278         return -EINVAL;
279     }
280 
281     model->mRecognitionCallback = callback;
282     model->mRecognitionCookie = cookie;
283 
284     sp<V2_1_ISoundTriggerHw> soundtrigger_2_1 = toService2_1(soundtrigger);
285     Return<int32_t> hidlReturn(0);
286 
287     if (!soundtrigger_2_1) {
288         ISoundTriggerHw::RecognitionConfig halConfig;
289         convertRecognitionConfigToHal(&halConfig, config);
290         {
291             AutoMutex lock(mHalLock);
292             hidlReturn = soundtrigger->startRecognition(model->mHalHandle, halConfig, this, handle);
293         }
294     } else {
295         V2_1_ISoundTriggerHw::RecognitionConfig halConfig;
296         auto result = convertRecognitionConfigToHal(&halConfig, config);
297         if (result.first) {
298             AutoMutex lock(mHalLock);
299             hidlReturn = soundtrigger_2_1->startRecognition_2_1(
300                     model->mHalHandle, halConfig, this, handle);
301         } else {
302             return NO_MEMORY;
303         }
304     }
305 
306     if (!hidlReturn.isOk()) {
307         ALOGE("startRecognition error %s", hidlReturn.description().c_str());
308         return FAILED_TRANSACTION;
309     }
310     return hidlReturn;
311 }
312 
stopRecognition(sound_model_handle_t handle)313 int SoundTriggerHalHidl::stopRecognition(sound_model_handle_t handle)
314 {
315     sp<ISoundTriggerHw> soundtrigger = getService();
316     if (soundtrigger == 0) {
317         return -ENODEV;
318     }
319 
320     sp<SoundModel> model = getModel(handle);
321     if (model == 0) {
322         ALOGE("stopRecognition model not found for handle %u", handle);
323         return -EINVAL;
324     }
325 
326     Return<int32_t> hidlReturn(0);
327     {
328         AutoMutex lock(mHalLock);
329         hidlReturn = soundtrigger->stopRecognition(model->mHalHandle);
330     }
331 
332     if (!hidlReturn.isOk()) {
333         ALOGE("stopRecognition error %s", hidlReturn.description().c_str());
334         return FAILED_TRANSACTION;
335     }
336     return hidlReturn;
337 }
338 
stopAllRecognitions()339 int SoundTriggerHalHidl::stopAllRecognitions()
340 {
341     sp<ISoundTriggerHw> soundtrigger = getService();
342     if (soundtrigger == 0) {
343         return -ENODEV;
344     }
345 
346     Return<int32_t> hidlReturn(0);
347     {
348         AutoMutex lock(mHalLock);
349         hidlReturn = soundtrigger->stopAllRecognitions();
350     }
351 
352     if (!hidlReturn.isOk()) {
353         ALOGE("stopAllRecognitions error %s", hidlReturn.description().c_str());
354         return FAILED_TRANSACTION;
355     }
356     return hidlReturn;
357 }
358 
SoundTriggerHalHidl(const char * moduleName)359 SoundTriggerHalHidl::SoundTriggerHalHidl(const char *moduleName)
360     : mModuleName(moduleName), mNextUniqueId(1)
361 {
362     LOG_ALWAYS_FATAL_IF(strcmp(mModuleName, "primary") != 0,
363             "Treble soundtrigger only supports primary module");
364 }
365 
~SoundTriggerHalHidl()366 SoundTriggerHalHidl::~SoundTriggerHalHidl()
367 {
368 }
369 
getService()370 sp<ISoundTriggerHw> SoundTriggerHalHidl::getService()
371 {
372     AutoMutex lock(mLock);
373     if (mISoundTrigger == 0) {
374         if (mModuleName == NULL) {
375             mModuleName = "primary";
376         }
377         mISoundTrigger = ISoundTriggerHw::getService();
378         if (mISoundTrigger != 0) {
379             mISoundTrigger->linkToDeath(HalDeathHandler::getInstance(), 0 /*cookie*/);
380         }
381     }
382     return mISoundTrigger;
383 }
384 
toService2_1(const sp<ISoundTriggerHw> & s)385 sp<V2_1_ISoundTriggerHw> SoundTriggerHalHidl::toService2_1(const sp<ISoundTriggerHw>& s)
386 {
387     auto castResult_2_1 = V2_1_ISoundTriggerHw::castFrom(s);
388     return castResult_2_1.isOk() ? static_cast<sp<V2_1_ISoundTriggerHw>>(castResult_2_1) : nullptr;
389 }
390 
getModel(sound_model_handle_t handle)391 sp<SoundTriggerHalHidl::SoundModel> SoundTriggerHalHidl::getModel(sound_model_handle_t handle)
392 {
393     AutoMutex lock(mLock);
394     return mSoundModels.valueFor(handle);
395 }
396 
removeModel(sound_model_handle_t handle)397 sp<SoundTriggerHalHidl::SoundModel> SoundTriggerHalHidl::removeModel(sound_model_handle_t handle)
398 {
399     AutoMutex lock(mLock);
400     sp<SoundModel> model = mSoundModels.valueFor(handle);
401     mSoundModels.removeItem(handle);
402     return model;
403 }
404 
nextUniqueId()405 uint32_t SoundTriggerHalHidl::nextUniqueId()
406 {
407     return (uint32_t) atomic_fetch_add_explicit(&mNextUniqueId,
408                 (uint_fast32_t) 1, memory_order_acq_rel);
409 }
410 
convertUuidToHal(Uuid * halUuid,const sound_trigger_uuid_t * uuid)411 void SoundTriggerHalHidl::convertUuidToHal(Uuid *halUuid,
412                                            const sound_trigger_uuid_t *uuid)
413 {
414     halUuid->timeLow = uuid->timeLow;
415     halUuid->timeMid = uuid->timeMid;
416     halUuid->versionAndTimeHigh = uuid->timeHiAndVersion;
417     halUuid->variantAndClockSeqHigh = uuid->clockSeq;
418     memcpy(halUuid->node.data(), &uuid->node[0], sizeof(uuid->node));
419 }
420 
convertUuidFromHal(sound_trigger_uuid_t * uuid,const Uuid * halUuid)421 void SoundTriggerHalHidl::convertUuidFromHal(sound_trigger_uuid_t *uuid,
422                                              const Uuid *halUuid)
423 {
424     uuid->timeLow = halUuid->timeLow;
425     uuid->timeMid = halUuid->timeMid;
426     uuid->timeHiAndVersion = halUuid->versionAndTimeHigh;
427     uuid->clockSeq = halUuid->variantAndClockSeqHigh;
428     memcpy(&uuid->node[0], halUuid->node.data(), sizeof(uuid->node));
429 }
430 
convertPropertiesFromHal(struct sound_trigger_properties * properties,const ISoundTriggerHw::Properties * halProperties)431 void SoundTriggerHalHidl::convertPropertiesFromHal(
432         struct sound_trigger_properties *properties,
433         const ISoundTriggerHw::Properties *halProperties)
434 {
435     strlcpy(properties->implementor,
436             halProperties->implementor.c_str(), SOUND_TRIGGER_MAX_STRING_LEN);
437     strlcpy(properties->description,
438             halProperties->description.c_str(), SOUND_TRIGGER_MAX_STRING_LEN);
439     properties->version = halProperties->version;
440     convertUuidFromHal(&properties->uuid, &halProperties->uuid);
441     properties->max_sound_models = halProperties->maxSoundModels;
442     properties->max_key_phrases = halProperties->maxKeyPhrases;
443     properties->max_users = halProperties->maxUsers;
444     properties->recognition_modes = halProperties->recognitionModes;
445     properties->capture_transition = (bool)halProperties->captureTransition;
446     properties->max_buffer_ms = halProperties->maxBufferMs;
447     properties->concurrent_capture = (bool)halProperties->concurrentCapture;
448     properties->trigger_in_event = (bool)halProperties->triggerInEvent;
449     properties->power_consumption_mw = halProperties->powerConsumptionMw;
450 }
451 
convertTriggerPhraseToHal(ISoundTriggerHw::Phrase * halTriggerPhrase,const struct sound_trigger_phrase * triggerPhrase)452 void SoundTriggerHalHidl::convertTriggerPhraseToHal(
453         ISoundTriggerHw::Phrase *halTriggerPhrase,
454         const struct sound_trigger_phrase *triggerPhrase)
455 {
456     halTriggerPhrase->id = triggerPhrase->id;
457     halTriggerPhrase->recognitionModes = triggerPhrase->recognition_mode;
458     halTriggerPhrase->users.setToExternal((uint32_t *)&triggerPhrase->users[0], triggerPhrase->num_users);
459     halTriggerPhrase->locale = triggerPhrase->locale;
460     halTriggerPhrase->text = triggerPhrase->text;
461 }
462 
463 
convertTriggerPhrasesToHal(hidl_vec<ISoundTriggerHw::Phrase> * halTriggerPhrases,struct sound_trigger_phrase_sound_model * keyPhraseModel)464 void SoundTriggerHalHidl::convertTriggerPhrasesToHal(
465         hidl_vec<ISoundTriggerHw::Phrase> *halTriggerPhrases,
466         struct sound_trigger_phrase_sound_model *keyPhraseModel)
467 {
468     halTriggerPhrases->resize(keyPhraseModel->num_phrases);
469     for (unsigned int i = 0; i < keyPhraseModel->num_phrases; i++) {
470         convertTriggerPhraseToHal(&(*halTriggerPhrases)[i], &keyPhraseModel->phrases[i]);
471     }
472 }
473 
convertSoundModelToHal(ISoundTriggerHw::SoundModel * halModel,const struct sound_trigger_sound_model * soundModel)474 void SoundTriggerHalHidl::convertSoundModelToHal(ISoundTriggerHw::SoundModel *halModel,
475         const struct sound_trigger_sound_model *soundModel)
476 {
477     halModel->type = (SoundModelType)soundModel->type;
478     convertUuidToHal(&halModel->uuid, &soundModel->uuid);
479     convertUuidToHal(&halModel->vendorUuid, &soundModel->vendor_uuid);
480     halModel->data.setToExternal((uint8_t *)soundModel + soundModel->data_offset, soundModel->data_size);
481 }
482 
convertSoundModelToHal(V2_1_ISoundTriggerHw::SoundModel * halModel,const struct sound_trigger_sound_model * soundModel)483 std::pair<bool, sp<IMemory>> SoundTriggerHalHidl::convertSoundModelToHal(
484         V2_1_ISoundTriggerHw::SoundModel *halModel,
485         const struct sound_trigger_sound_model *soundModel)
486 {
487     convertSoundModelToHal(&halModel->header, soundModel);
488     return moveVectorToMemory(&halModel->header.data, &halModel->data);
489 }
490 
convertPhraseSoundModelToHal(ISoundTriggerHw::PhraseSoundModel * halKeyPhraseModel,const struct sound_trigger_sound_model * soundModel)491 void SoundTriggerHalHidl::convertPhraseSoundModelToHal(
492         ISoundTriggerHw::PhraseSoundModel *halKeyPhraseModel,
493         const struct sound_trigger_sound_model *soundModel)
494 {
495     struct sound_trigger_phrase_sound_model *keyPhraseModel =
496             (struct sound_trigger_phrase_sound_model *)soundModel;
497     convertTriggerPhrasesToHal(&halKeyPhraseModel->phrases, keyPhraseModel);
498     convertSoundModelToHal(&halKeyPhraseModel->common, soundModel);
499 }
500 
convertPhraseSoundModelToHal(V2_1_ISoundTriggerHw::PhraseSoundModel * halKeyPhraseModel,const struct sound_trigger_sound_model * soundModel)501 std::pair<bool, sp<IMemory>> SoundTriggerHalHidl::convertPhraseSoundModelToHal(
502         V2_1_ISoundTriggerHw::PhraseSoundModel *halKeyPhraseModel,
503         const struct sound_trigger_sound_model *soundModel)
504 {
505     struct sound_trigger_phrase_sound_model *keyPhraseModel =
506             (struct sound_trigger_phrase_sound_model *)soundModel;
507     convertTriggerPhrasesToHal(&halKeyPhraseModel->phrases, keyPhraseModel);
508     return convertSoundModelToHal(&halKeyPhraseModel->common, soundModel);
509 }
510 
convertPhraseRecognitionExtraToHal(PhraseRecognitionExtra * halExtra,const struct sound_trigger_phrase_recognition_extra * extra)511 void SoundTriggerHalHidl::convertPhraseRecognitionExtraToHal(
512         PhraseRecognitionExtra *halExtra,
513         const struct sound_trigger_phrase_recognition_extra *extra)
514 {
515     halExtra->id = extra->id;
516     halExtra->recognitionModes = extra->recognition_modes;
517     halExtra->confidenceLevel = extra->confidence_level;
518     halExtra->levels.resize(extra->num_levels);
519     for (unsigned int i = 0; i < extra->num_levels; i++) {
520         halExtra->levels[i].userId = extra->levels[i].user_id;
521         halExtra->levels[i].levelPercent = extra->levels[i].level;
522     }
523 }
524 
convertRecognitionConfigToHal(ISoundTriggerHw::RecognitionConfig * halConfig,const struct sound_trigger_recognition_config * config)525 void SoundTriggerHalHidl::convertRecognitionConfigToHal(
526         ISoundTriggerHw::RecognitionConfig *halConfig,
527         const struct sound_trigger_recognition_config *config)
528 {
529     halConfig->captureHandle = config->capture_handle;
530     halConfig->captureDevice = (AudioDevice)config->capture_device;
531     halConfig->captureRequested = (uint32_t)config->capture_requested;
532 
533     halConfig->phrases.resize(config->num_phrases);
534     for (unsigned int i = 0; i < config->num_phrases; i++) {
535         convertPhraseRecognitionExtraToHal(&halConfig->phrases[i],
536                                   &config->phrases[i]);
537     }
538 
539     halConfig->data.setToExternal((uint8_t *)config + config->data_offset, config->data_size);
540 }
541 
convertRecognitionConfigToHal(V2_1_ISoundTriggerHw::RecognitionConfig * halConfig,const struct sound_trigger_recognition_config * config)542 std::pair<bool, sp<IMemory>> SoundTriggerHalHidl::convertRecognitionConfigToHal(
543         V2_1_ISoundTriggerHw::RecognitionConfig *halConfig,
544         const struct sound_trigger_recognition_config *config)
545 {
546     convertRecognitionConfigToHal(&halConfig->header, config);
547     return moveVectorToMemory(&halConfig->header.data, &halConfig->data);
548 }
549 
550 
551 // ISoundTriggerHwCallback
recognitionCallback(const V2_0_ISoundTriggerHwCallback::RecognitionEvent & halEvent,CallbackCookie cookie)552 ::android::hardware::Return<void> SoundTriggerHalHidl::recognitionCallback(
553         const V2_0_ISoundTriggerHwCallback::RecognitionEvent& halEvent,
554         CallbackCookie cookie)
555 {
556     sp<SoundModel> model;
557     {
558         AutoMutex lock(mLock);
559         model = mSoundModels.valueFor((SoundModelHandle)cookie);
560         if (model == 0) {
561             return Return<void>();
562         }
563     }
564     struct sound_trigger_recognition_event *event = convertRecognitionEventFromHal(&halEvent);
565     if (event == NULL) {
566         return Return<void>();
567     }
568     event->model = model->mHandle;
569     model->mRecognitionCallback(event, model->mRecognitionCookie);
570 
571     free(event);
572 
573     return Return<void>();
574 }
575 
phraseRecognitionCallback(const V2_0_ISoundTriggerHwCallback::PhraseRecognitionEvent & halEvent,CallbackCookie cookie)576 ::android::hardware::Return<void> SoundTriggerHalHidl::phraseRecognitionCallback(
577         const V2_0_ISoundTriggerHwCallback::PhraseRecognitionEvent& halEvent,
578         CallbackCookie cookie)
579 {
580     sp<SoundModel> model;
581     {
582         AutoMutex lock(mLock);
583         model = mSoundModels.valueFor((SoundModelHandle)cookie);
584         if (model == 0) {
585             return Return<void>();
586         }
587     }
588 
589     struct sound_trigger_phrase_recognition_event *event =
590             convertPhraseRecognitionEventFromHal(&halEvent);
591     if (event == NULL) {
592         return Return<void>();
593     }
594     event->common.model = model->mHandle;
595     model->mRecognitionCallback(&event->common, model->mRecognitionCookie);
596 
597     free(event);
598 
599     return Return<void>();
600 }
601 
soundModelCallback(const V2_0_ISoundTriggerHwCallback::ModelEvent & halEvent,CallbackCookie cookie)602 ::android::hardware::Return<void> SoundTriggerHalHidl::soundModelCallback(
603         const V2_0_ISoundTriggerHwCallback::ModelEvent& halEvent,
604         CallbackCookie cookie)
605 {
606     sp<SoundModel> model;
607     {
608         AutoMutex lock(mLock);
609         model = mSoundModels.valueFor((SoundModelHandle)cookie);
610         if (model == 0) {
611             return Return<void>();
612         }
613     }
614 
615     struct sound_trigger_model_event *event = convertSoundModelEventFromHal(&halEvent);
616     if (event == NULL) {
617         return Return<void>();
618     }
619 
620     event->model = model->mHandle;
621     model->mSoundModelCallback(event, model->mSoundModelCookie);
622 
623     free(event);
624 
625     return Return<void>();
626 }
627 
recognitionCallback_2_1(const ISoundTriggerHwCallback::RecognitionEvent & event,CallbackCookie cookie)628 ::android::hardware::Return<void> SoundTriggerHalHidl::recognitionCallback_2_1(
629         const ISoundTriggerHwCallback::RecognitionEvent& event, CallbackCookie cookie) {
630     // The data vector in the 'header' part of V2.1 structure is empty, thus copying is cheap.
631     V2_0_ISoundTriggerHwCallback::RecognitionEvent event_2_0 = event.header;
632     auto result = memoryAsVector(event.data, &event_2_0.data);
633     return result.first ? recognitionCallback(event_2_0, cookie) : Void();
634 }
635 
phraseRecognitionCallback_2_1(const ISoundTriggerHwCallback::PhraseRecognitionEvent & event,int32_t cookie)636 ::android::hardware::Return<void> SoundTriggerHalHidl::phraseRecognitionCallback_2_1(
637         const ISoundTriggerHwCallback::PhraseRecognitionEvent& event, int32_t cookie) {
638     V2_0_ISoundTriggerHwCallback::PhraseRecognitionEvent event_2_0;
639     // The data vector in the 'header' part of V2.1 structure is empty, thus copying is cheap.
640     event_2_0.common = event.common.header;
641     event_2_0.phraseExtras.setToExternal(
642             const_cast<PhraseRecognitionExtra*>(event.phraseExtras.data()),
643             event.phraseExtras.size());
644     auto result = memoryAsVector(event.common.data, &event_2_0.common.data);
645     return result.first ? phraseRecognitionCallback(event_2_0, cookie) : Void();
646 }
647 
soundModelCallback_2_1(const ISoundTriggerHwCallback::ModelEvent & event,CallbackCookie cookie)648 ::android::hardware::Return<void> SoundTriggerHalHidl::soundModelCallback_2_1(
649         const ISoundTriggerHwCallback::ModelEvent& event, CallbackCookie cookie) {
650     // The data vector in the 'header' part of V2.1 structure is empty, thus copying is cheap.
651     V2_0_ISoundTriggerHwCallback::ModelEvent event_2_0 = event.header;
652     auto result = memoryAsVector(event.data, &event_2_0.data);
653     return result.first ? soundModelCallback(event_2_0, cookie) : Void();
654 }
655 
656 
convertSoundModelEventFromHal(const V2_0_ISoundTriggerHwCallback::ModelEvent * halEvent)657 struct sound_trigger_model_event *SoundTriggerHalHidl::convertSoundModelEventFromHal(
658                                               const V2_0_ISoundTriggerHwCallback::ModelEvent *halEvent)
659 {
660     struct sound_trigger_model_event *event = (struct sound_trigger_model_event *)malloc(
661             sizeof(struct sound_trigger_model_event) +
662             halEvent->data.size());
663     if (event == NULL) {
664         return NULL;
665     }
666 
667     event->status = (int)halEvent->status;
668     // event->model to be set by caller
669     event->data_offset = sizeof(struct sound_trigger_model_event);
670     event->data_size = halEvent->data.size();
671     uint8_t *dst = (uint8_t *)event + event->data_offset;
672     uint8_t *src = (uint8_t *)&halEvent->data[0];
673     memcpy(dst, src, halEvent->data.size());
674 
675     return event;
676 }
677 
convertPhraseRecognitionExtraFromHal(struct sound_trigger_phrase_recognition_extra * extra,const PhraseRecognitionExtra * halExtra)678 void SoundTriggerHalHidl::convertPhraseRecognitionExtraFromHal(
679         struct sound_trigger_phrase_recognition_extra *extra,
680         const PhraseRecognitionExtra *halExtra)
681 {
682     extra->id = halExtra->id;
683     extra->recognition_modes = halExtra->recognitionModes;
684     extra->confidence_level = halExtra->confidenceLevel;
685 
686     size_t i;
687     for (i = 0; i < halExtra->levels.size() && i < SOUND_TRIGGER_MAX_USERS; i++) {
688         extra->levels[i].user_id = halExtra->levels[i].userId;
689         extra->levels[i].level = halExtra->levels[i].levelPercent;
690     }
691     extra->num_levels = (unsigned int)i;
692 }
693 
694 
convertPhraseRecognitionEventFromHal(const V2_0_ISoundTriggerHwCallback::PhraseRecognitionEvent * halPhraseEvent)695 struct sound_trigger_phrase_recognition_event* SoundTriggerHalHidl::convertPhraseRecognitionEventFromHal(
696         const V2_0_ISoundTriggerHwCallback::PhraseRecognitionEvent *halPhraseEvent)
697 {
698     if (halPhraseEvent->common.type != SoundModelType::KEYPHRASE) {
699         ALOGE("Received non-keyphrase event type as PhraseRecognitionEvent");
700         return NULL;
701     }
702     struct sound_trigger_phrase_recognition_event *phraseEvent =
703             (struct sound_trigger_phrase_recognition_event *)malloc(
704                     sizeof(struct sound_trigger_phrase_recognition_event) +
705                     halPhraseEvent->common.data.size());
706     if (phraseEvent == NULL) {
707         return NULL;
708     }
709     phraseEvent->common.data_offset = sizeof(sound_trigger_phrase_recognition_event);
710 
711     for (unsigned int i = 0; i < halPhraseEvent->phraseExtras.size(); i++) {
712         convertPhraseRecognitionExtraFromHal(&phraseEvent->phrase_extras[i],
713                                              &halPhraseEvent->phraseExtras[i]);
714     }
715     phraseEvent->num_phrases = halPhraseEvent->phraseExtras.size();
716 
717     fillRecognitionEventFromHal(&phraseEvent->common, &halPhraseEvent->common);
718     return phraseEvent;
719 }
720 
convertRecognitionEventFromHal(const V2_0_ISoundTriggerHwCallback::RecognitionEvent * halEvent)721 struct sound_trigger_recognition_event *SoundTriggerHalHidl::convertRecognitionEventFromHal(
722         const V2_0_ISoundTriggerHwCallback::RecognitionEvent *halEvent)
723 {
724     if (halEvent->type == SoundModelType::KEYPHRASE) {
725         ALOGE("Received keyphrase event type as RecognitionEvent");
726         return NULL;
727     }
728     struct sound_trigger_recognition_event *event;
729     event = (struct sound_trigger_recognition_event *)malloc(
730             sizeof(struct sound_trigger_recognition_event) + halEvent->data.size());
731     if (event == NULL) {
732         return NULL;
733     }
734     event->data_offset = sizeof(sound_trigger_recognition_event);
735 
736     fillRecognitionEventFromHal(event, halEvent);
737     return event;
738 }
739 
fillRecognitionEventFromHal(struct sound_trigger_recognition_event * event,const V2_0_ISoundTriggerHwCallback::RecognitionEvent * halEvent)740 void SoundTriggerHalHidl::fillRecognitionEventFromHal(
741         struct sound_trigger_recognition_event *event,
742         const V2_0_ISoundTriggerHwCallback::RecognitionEvent *halEvent)
743 {
744     event->status = (int)halEvent->status;
745     event->type = (sound_trigger_sound_model_type_t)halEvent->type;
746     // event->model to be set by caller
747     event->capture_available = (bool)halEvent->captureAvailable;
748     event->capture_session = halEvent->captureSession;
749     event->capture_delay_ms = halEvent->captureDelayMs;
750     event->capture_preamble_ms = halEvent->capturePreambleMs;
751     event->trigger_in_data = (bool)halEvent->triggerInData;
752     event->audio_config.sample_rate = halEvent->audioConfig.sampleRateHz;
753     event->audio_config.channel_mask = (audio_channel_mask_t)halEvent->audioConfig.channelMask;
754     event->audio_config.format = (audio_format_t)halEvent->audioConfig.format;
755 
756     event->data_size = halEvent->data.size();
757     uint8_t *dst = (uint8_t *)event + event->data_offset;
758     uint8_t *src = (uint8_t *)&halEvent->data[0];
759     memcpy(dst, src, halEvent->data.size());
760 }
761 
762 } // namespace android
763