• 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     sp<V2_2_ISoundTriggerHw> soundtrigger_2_2 = toService2_2(soundtrigger);
172     if (sound_model->type == SOUND_MODEL_TYPE_KEYPHRASE) {
173         if (soundtrigger_2_2) {
174             V2_2_ISoundTriggerHw::PhraseSoundModel halSoundModel;
175             auto result = convertPhraseSoundModelToHal(&halSoundModel, sound_model);
176             if (result.first) {
177                 AutoMutex lock(mHalLock);
178                 hidlReturn = soundtrigger_2_2->loadPhraseSoundModel_2_1(
179                         halSoundModel,
180                         this, modelId, [&](int32_t retval, auto res) {
181                             ret = retval;
182                             halHandle = res;
183                         });
184             } else {
185                 return NO_MEMORY;
186             }
187         } else if (soundtrigger_2_1) {
188             V2_1_ISoundTriggerHw::PhraseSoundModel halSoundModel;
189             auto result = convertPhraseSoundModelToHal(&halSoundModel, sound_model);
190             if (result.first) {
191                 AutoMutex lock(mHalLock);
192                 hidlReturn = soundtrigger_2_1->loadPhraseSoundModel_2_1(
193                         halSoundModel,
194                         this, modelId, [&](int32_t retval, auto res) {
195                             ret = retval;
196                             halHandle = res;
197                         });
198             } else {
199                 return NO_MEMORY;
200             }
201         } else {
202             ISoundTriggerHw::PhraseSoundModel halSoundModel;
203             convertPhraseSoundModelToHal(&halSoundModel, sound_model);
204             AutoMutex lock(mHalLock);
205             hidlReturn = soundtrigger->loadPhraseSoundModel(
206                     halSoundModel,
207                     this, modelId, [&](int32_t retval, auto res) {
208                         ret = retval;
209                         halHandle = res;
210                     });
211         }
212     } else {
213         if (soundtrigger_2_2) {
214             V2_2_ISoundTriggerHw::SoundModel halSoundModel;
215             auto result = convertSoundModelToHal(&halSoundModel, sound_model);
216             if (result.first) {
217                 AutoMutex lock(mHalLock);
218                 hidlReturn = soundtrigger_2_2->loadSoundModel_2_1(halSoundModel,
219                         this, modelId, [&](int32_t retval, auto res) {
220                             ret = retval;
221                             halHandle = res;
222                         });
223             } else {
224                 return NO_MEMORY;
225             }
226         } else if (soundtrigger_2_1) {
227             V2_1_ISoundTriggerHw::SoundModel halSoundModel;
228             auto result = convertSoundModelToHal(&halSoundModel, sound_model);
229             if (result.first) {
230                 AutoMutex lock(mHalLock);
231                 hidlReturn = soundtrigger_2_1->loadSoundModel_2_1(halSoundModel,
232                         this, modelId, [&](int32_t retval, auto res) {
233                             ret = retval;
234                             halHandle = res;
235                         });
236             } else {
237                 return NO_MEMORY;
238             }
239         } else {
240             ISoundTriggerHw::SoundModel halSoundModel;
241             convertSoundModelToHal(&halSoundModel, sound_model);
242             AutoMutex lock(mHalLock);
243             hidlReturn = soundtrigger->loadSoundModel(halSoundModel,
244                     this, modelId, [&](int32_t retval, auto res) {
245                         ret = retval;
246                         halHandle = res;
247                     });
248         }
249     }
250 
251     if (hidlReturn.isOk()) {
252         if (ret == 0) {
253             AutoMutex lock(mLock);
254             *handle = (sound_model_handle_t)modelId;
255             sp<SoundModel> model = new SoundModel(*handle, callback, cookie, halHandle);
256             mSoundModels.add(*handle, model);
257         }
258     } else {
259         ALOGE("loadSoundModel error %s", hidlReturn.description().c_str());
260         return FAILED_TRANSACTION;
261     }
262 
263     return ret;
264 }
265 
unloadSoundModel(sound_model_handle_t handle)266 int SoundTriggerHalHidl::unloadSoundModel(sound_model_handle_t handle)
267 {
268     sp<ISoundTriggerHw> soundtrigger = getService();
269     if (soundtrigger == 0) {
270         return -ENODEV;
271     }
272 
273     sp<SoundModel> model = removeModel(handle);
274     if (model == 0) {
275         ALOGE("unloadSoundModel model not found for handle %u", handle);
276         return -EINVAL;
277     }
278 
279     Return<int32_t> hidlReturn(0);
280     {
281         AutoMutex lock(mHalLock);
282         hidlReturn = soundtrigger->unloadSoundModel(model->mHalHandle);
283     }
284 
285     if (!hidlReturn.isOk()) {
286         ALOGE("unloadSoundModel error %s", hidlReturn.description().c_str());
287         return FAILED_TRANSACTION;
288     }
289 
290     return hidlReturn;
291 }
292 
startRecognition(sound_model_handle_t handle,const struct sound_trigger_recognition_config * config,recognition_callback_t callback,void * cookie)293 int SoundTriggerHalHidl::startRecognition(sound_model_handle_t handle,
294                          const struct sound_trigger_recognition_config *config,
295                          recognition_callback_t callback,
296                          void *cookie)
297 {
298     sp<ISoundTriggerHw> soundtrigger = getService();
299     if (soundtrigger == 0) {
300         return -ENODEV;
301     }
302 
303     sp<SoundModel> model = getModel(handle);
304     if (model == 0) {
305         ALOGE("startRecognition model not found for handle %u", handle);
306         return -EINVAL;
307     }
308 
309     model->mRecognitionCallback = callback;
310     model->mRecognitionCookie = cookie;
311 
312     sp<V2_1_ISoundTriggerHw> soundtrigger_2_1 = toService2_1(soundtrigger);
313     sp<V2_2_ISoundTriggerHw> soundtrigger_2_2 = toService2_2(soundtrigger);
314     Return<int32_t> hidlReturn(0);
315 
316     if (soundtrigger_2_2) {
317         V2_2_ISoundTriggerHw::RecognitionConfig halConfig;
318         auto result = convertRecognitionConfigToHal(&halConfig, config);
319         if (result.first) {
320             AutoMutex lock(mHalLock);
321             hidlReturn = soundtrigger_2_2->startRecognition_2_1(
322                     model->mHalHandle, halConfig, this, handle);
323         } else {
324             return NO_MEMORY;
325         }
326     } else if (soundtrigger_2_1) {
327         V2_1_ISoundTriggerHw::RecognitionConfig halConfig;
328         auto result = convertRecognitionConfigToHal(&halConfig, config);
329         if (result.first) {
330             AutoMutex lock(mHalLock);
331             hidlReturn = soundtrigger_2_1->startRecognition_2_1(
332                     model->mHalHandle, halConfig, this, handle);
333         } else {
334             return NO_MEMORY;
335         }
336     } else {
337         ISoundTriggerHw::RecognitionConfig halConfig;
338         convertRecognitionConfigToHal(&halConfig, config);
339         {
340             AutoMutex lock(mHalLock);
341             hidlReturn = soundtrigger->startRecognition(model->mHalHandle, halConfig, this, handle);
342         }
343     }
344 
345     if (!hidlReturn.isOk()) {
346         ALOGE("startRecognition error %s", hidlReturn.description().c_str());
347         return FAILED_TRANSACTION;
348     }
349     return hidlReturn;
350 }
351 
stopRecognition(sound_model_handle_t handle)352 int SoundTriggerHalHidl::stopRecognition(sound_model_handle_t handle)
353 {
354     sp<ISoundTriggerHw> soundtrigger = getService();
355     if (soundtrigger == 0) {
356         return -ENODEV;
357     }
358 
359     sp<SoundModel> model = getModel(handle);
360     if (model == 0) {
361         ALOGE("stopRecognition model not found for handle %u", handle);
362         return -EINVAL;
363     }
364 
365     Return<int32_t> hidlReturn(0);
366     {
367         AutoMutex lock(mHalLock);
368         hidlReturn = soundtrigger->stopRecognition(model->mHalHandle);
369     }
370 
371     if (!hidlReturn.isOk()) {
372         ALOGE("stopRecognition error %s", hidlReturn.description().c_str());
373         return FAILED_TRANSACTION;
374     }
375     return hidlReturn;
376 }
377 
stopAllRecognitions()378 int SoundTriggerHalHidl::stopAllRecognitions()
379 {
380     sp<ISoundTriggerHw> soundtrigger = getService();
381     if (soundtrigger == 0) {
382         return -ENODEV;
383     }
384 
385     Return<int32_t> hidlReturn(0);
386     {
387         AutoMutex lock(mHalLock);
388         hidlReturn = soundtrigger->stopAllRecognitions();
389     }
390 
391     if (!hidlReturn.isOk()) {
392         ALOGE("stopAllRecognitions error %s", hidlReturn.description().c_str());
393         return FAILED_TRANSACTION;
394     }
395     return hidlReturn;
396 }
397 
getModelState(sound_model_handle_t handle)398 int SoundTriggerHalHidl::getModelState(sound_model_handle_t handle)
399 {
400     sp<ISoundTriggerHw> soundtrigger = getService();
401     if (soundtrigger == 0) {
402         return -ENODEV;
403     }
404 
405     sp<V2_2_ISoundTriggerHw> soundtrigger_2_2 = toService2_2(soundtrigger);
406     if (soundtrigger_2_2 == 0) {
407         ALOGE("getModelState not supported");
408         return -ENODEV;
409     }
410 
411     sp<SoundModel> model = getModel(handle);
412     if (model == 0) {
413         ALOGE("getModelState model not found for handle %u", handle);
414         return -EINVAL;
415     }
416 
417     int ret = NO_ERROR;
418     Return<int32_t> hidlReturn(0);
419     {
420         AutoMutex lock(mHalLock);
421         hidlReturn = soundtrigger_2_2->getModelState(model->mHalHandle);
422     }
423     if (!hidlReturn.isOk()) {
424         ALOGE("getModelState error %s", hidlReturn.description().c_str());
425         ret = FAILED_TRANSACTION;
426     }
427     return ret;
428 }
429 
SoundTriggerHalHidl(const char * moduleName)430 SoundTriggerHalHidl::SoundTriggerHalHidl(const char *moduleName)
431     : mModuleName(moduleName), mNextUniqueId(1)
432 {
433     LOG_ALWAYS_FATAL_IF(strcmp(mModuleName, "primary") != 0,
434             "Treble soundtrigger only supports primary module");
435 }
436 
~SoundTriggerHalHidl()437 SoundTriggerHalHidl::~SoundTriggerHalHidl()
438 {
439 }
440 
getService()441 sp<ISoundTriggerHw> SoundTriggerHalHidl::getService()
442 {
443     AutoMutex lock(mLock);
444     if (mISoundTrigger == 0) {
445         if (mModuleName == NULL) {
446             mModuleName = "primary";
447         }
448         mISoundTrigger = ISoundTriggerHw::getService();
449         if (mISoundTrigger != 0) {
450             mISoundTrigger->linkToDeath(HalDeathHandler::getInstance(), 0 /*cookie*/);
451         }
452     }
453     return mISoundTrigger;
454 }
455 
toService2_1(const sp<ISoundTriggerHw> & s)456 sp<V2_1_ISoundTriggerHw> SoundTriggerHalHidl::toService2_1(const sp<ISoundTriggerHw>& s)
457 {
458     auto castResult_2_1 = V2_1_ISoundTriggerHw::castFrom(s);
459     return castResult_2_1.isOk() ? static_cast<sp<V2_1_ISoundTriggerHw>>(castResult_2_1) : nullptr;
460 }
461 
toService2_2(const sp<ISoundTriggerHw> & s)462 sp<V2_2_ISoundTriggerHw> SoundTriggerHalHidl::toService2_2(const sp<ISoundTriggerHw>& s)
463 {
464     auto castResult_2_2 = V2_2_ISoundTriggerHw::castFrom(s);
465     return castResult_2_2.isOk() ? static_cast<sp<V2_2_ISoundTriggerHw>>(castResult_2_2) : nullptr;
466 }
467 
getModel(sound_model_handle_t handle)468 sp<SoundTriggerHalHidl::SoundModel> SoundTriggerHalHidl::getModel(sound_model_handle_t handle)
469 {
470     AutoMutex lock(mLock);
471     return mSoundModels.valueFor(handle);
472 }
473 
removeModel(sound_model_handle_t handle)474 sp<SoundTriggerHalHidl::SoundModel> SoundTriggerHalHidl::removeModel(sound_model_handle_t handle)
475 {
476     AutoMutex lock(mLock);
477     sp<SoundModel> model = mSoundModels.valueFor(handle);
478     mSoundModels.removeItem(handle);
479     return model;
480 }
481 
nextUniqueId()482 uint32_t SoundTriggerHalHidl::nextUniqueId()
483 {
484     return (uint32_t) atomic_fetch_add_explicit(&mNextUniqueId,
485                 (uint_fast32_t) 1, memory_order_acq_rel);
486 }
487 
convertUuidToHal(Uuid * halUuid,const sound_trigger_uuid_t * uuid)488 void SoundTriggerHalHidl::convertUuidToHal(Uuid *halUuid,
489                                            const sound_trigger_uuid_t *uuid)
490 {
491     halUuid->timeLow = uuid->timeLow;
492     halUuid->timeMid = uuid->timeMid;
493     halUuid->versionAndTimeHigh = uuid->timeHiAndVersion;
494     halUuid->variantAndClockSeqHigh = uuid->clockSeq;
495     memcpy(halUuid->node.data(), &uuid->node[0], sizeof(uuid->node));
496 }
497 
convertUuidFromHal(sound_trigger_uuid_t * uuid,const Uuid * halUuid)498 void SoundTriggerHalHidl::convertUuidFromHal(sound_trigger_uuid_t *uuid,
499                                              const Uuid *halUuid)
500 {
501     uuid->timeLow = halUuid->timeLow;
502     uuid->timeMid = halUuid->timeMid;
503     uuid->timeHiAndVersion = halUuid->versionAndTimeHigh;
504     uuid->clockSeq = halUuid->variantAndClockSeqHigh;
505     memcpy(&uuid->node[0], halUuid->node.data(), sizeof(uuid->node));
506 }
507 
convertPropertiesFromHal(struct sound_trigger_properties * properties,const ISoundTriggerHw::Properties * halProperties)508 void SoundTriggerHalHidl::convertPropertiesFromHal(
509         struct sound_trigger_properties *properties,
510         const ISoundTriggerHw::Properties *halProperties)
511 {
512     strlcpy(properties->implementor,
513             halProperties->implementor.c_str(), SOUND_TRIGGER_MAX_STRING_LEN);
514     strlcpy(properties->description,
515             halProperties->description.c_str(), SOUND_TRIGGER_MAX_STRING_LEN);
516     properties->version = halProperties->version;
517     convertUuidFromHal(&properties->uuid, &halProperties->uuid);
518     properties->max_sound_models = halProperties->maxSoundModels;
519     properties->max_key_phrases = halProperties->maxKeyPhrases;
520     properties->max_users = halProperties->maxUsers;
521     properties->recognition_modes = halProperties->recognitionModes;
522     properties->capture_transition = (bool)halProperties->captureTransition;
523     properties->max_buffer_ms = halProperties->maxBufferMs;
524     properties->concurrent_capture = (bool)halProperties->concurrentCapture;
525     properties->trigger_in_event = (bool)halProperties->triggerInEvent;
526     properties->power_consumption_mw = halProperties->powerConsumptionMw;
527 }
528 
convertTriggerPhraseToHal(ISoundTriggerHw::Phrase * halTriggerPhrase,const struct sound_trigger_phrase * triggerPhrase)529 void SoundTriggerHalHidl::convertTriggerPhraseToHal(
530         ISoundTriggerHw::Phrase *halTriggerPhrase,
531         const struct sound_trigger_phrase *triggerPhrase)
532 {
533     halTriggerPhrase->id = triggerPhrase->id;
534     halTriggerPhrase->recognitionModes = triggerPhrase->recognition_mode;
535     halTriggerPhrase->users.setToExternal((uint32_t *)&triggerPhrase->users[0], triggerPhrase->num_users);
536     halTriggerPhrase->locale = triggerPhrase->locale;
537     halTriggerPhrase->text = triggerPhrase->text;
538 }
539 
540 
convertTriggerPhrasesToHal(hidl_vec<ISoundTriggerHw::Phrase> * halTriggerPhrases,struct sound_trigger_phrase_sound_model * keyPhraseModel)541 void SoundTriggerHalHidl::convertTriggerPhrasesToHal(
542         hidl_vec<ISoundTriggerHw::Phrase> *halTriggerPhrases,
543         struct sound_trigger_phrase_sound_model *keyPhraseModel)
544 {
545     halTriggerPhrases->resize(keyPhraseModel->num_phrases);
546     for (unsigned int i = 0; i < keyPhraseModel->num_phrases; i++) {
547         convertTriggerPhraseToHal(&(*halTriggerPhrases)[i], &keyPhraseModel->phrases[i]);
548     }
549 }
550 
convertSoundModelToHal(ISoundTriggerHw::SoundModel * halModel,const struct sound_trigger_sound_model * soundModel)551 void SoundTriggerHalHidl::convertSoundModelToHal(ISoundTriggerHw::SoundModel *halModel,
552         const struct sound_trigger_sound_model *soundModel)
553 {
554     halModel->type = (SoundModelType)soundModel->type;
555     convertUuidToHal(&halModel->uuid, &soundModel->uuid);
556     convertUuidToHal(&halModel->vendorUuid, &soundModel->vendor_uuid);
557     halModel->data.setToExternal((uint8_t *)soundModel + soundModel->data_offset, soundModel->data_size);
558 }
559 
convertSoundModelToHal(V2_1_ISoundTriggerHw::SoundModel * halModel,const struct sound_trigger_sound_model * soundModel)560 std::pair<bool, sp<IMemory>> SoundTriggerHalHidl::convertSoundModelToHal(
561         V2_1_ISoundTriggerHw::SoundModel *halModel,
562         const struct sound_trigger_sound_model *soundModel)
563 {
564     convertSoundModelToHal(&halModel->header, soundModel);
565     return moveVectorToMemory(&halModel->header.data, &halModel->data);
566 }
567 
convertPhraseSoundModelToHal(ISoundTriggerHw::PhraseSoundModel * halKeyPhraseModel,const struct sound_trigger_sound_model * soundModel)568 void SoundTriggerHalHidl::convertPhraseSoundModelToHal(
569         ISoundTriggerHw::PhraseSoundModel *halKeyPhraseModel,
570         const struct sound_trigger_sound_model *soundModel)
571 {
572     struct sound_trigger_phrase_sound_model *keyPhraseModel =
573             (struct sound_trigger_phrase_sound_model *)soundModel;
574     convertTriggerPhrasesToHal(&halKeyPhraseModel->phrases, keyPhraseModel);
575     convertSoundModelToHal(&halKeyPhraseModel->common, soundModel);
576 }
577 
convertPhraseSoundModelToHal(V2_1_ISoundTriggerHw::PhraseSoundModel * halKeyPhraseModel,const struct sound_trigger_sound_model * soundModel)578 std::pair<bool, sp<IMemory>> SoundTriggerHalHidl::convertPhraseSoundModelToHal(
579         V2_1_ISoundTriggerHw::PhraseSoundModel *halKeyPhraseModel,
580         const struct sound_trigger_sound_model *soundModel)
581 {
582     struct sound_trigger_phrase_sound_model *keyPhraseModel =
583             (struct sound_trigger_phrase_sound_model *)soundModel;
584     convertTriggerPhrasesToHal(&halKeyPhraseModel->phrases, keyPhraseModel);
585     return convertSoundModelToHal(&halKeyPhraseModel->common, soundModel);
586 }
587 
convertPhraseRecognitionExtraToHal(PhraseRecognitionExtra * halExtra,const struct sound_trigger_phrase_recognition_extra * extra)588 void SoundTriggerHalHidl::convertPhraseRecognitionExtraToHal(
589         PhraseRecognitionExtra *halExtra,
590         const struct sound_trigger_phrase_recognition_extra *extra)
591 {
592     halExtra->id = extra->id;
593     halExtra->recognitionModes = extra->recognition_modes;
594     halExtra->confidenceLevel = extra->confidence_level;
595     halExtra->levels.resize(extra->num_levels);
596     for (unsigned int i = 0; i < extra->num_levels; i++) {
597         halExtra->levels[i].userId = extra->levels[i].user_id;
598         halExtra->levels[i].levelPercent = extra->levels[i].level;
599     }
600 }
601 
convertRecognitionConfigToHal(ISoundTriggerHw::RecognitionConfig * halConfig,const struct sound_trigger_recognition_config * config)602 void SoundTriggerHalHidl::convertRecognitionConfigToHal(
603         ISoundTriggerHw::RecognitionConfig *halConfig,
604         const struct sound_trigger_recognition_config *config)
605 {
606     halConfig->captureHandle = config->capture_handle;
607     halConfig->captureDevice = (AudioDevice)config->capture_device;
608     halConfig->captureRequested = (uint32_t)config->capture_requested;
609 
610     halConfig->phrases.resize(config->num_phrases);
611     for (unsigned int i = 0; i < config->num_phrases; i++) {
612         convertPhraseRecognitionExtraToHal(&halConfig->phrases[i],
613                                   &config->phrases[i]);
614     }
615 
616     halConfig->data.setToExternal((uint8_t *)config + config->data_offset, config->data_size);
617 }
618 
convertRecognitionConfigToHal(V2_1_ISoundTriggerHw::RecognitionConfig * halConfig,const struct sound_trigger_recognition_config * config)619 std::pair<bool, sp<IMemory>> SoundTriggerHalHidl::convertRecognitionConfigToHal(
620         V2_1_ISoundTriggerHw::RecognitionConfig *halConfig,
621         const struct sound_trigger_recognition_config *config)
622 {
623     convertRecognitionConfigToHal(&halConfig->header, config);
624     return moveVectorToMemory(&halConfig->header.data, &halConfig->data);
625 }
626 
627 
628 // ISoundTriggerHwCallback
recognitionCallback(const V2_0_ISoundTriggerHwCallback::RecognitionEvent & halEvent,CallbackCookie cookie)629 ::android::hardware::Return<void> SoundTriggerHalHidl::recognitionCallback(
630         const V2_0_ISoundTriggerHwCallback::RecognitionEvent& halEvent,
631         CallbackCookie cookie)
632 {
633     sp<SoundModel> model;
634     {
635         AutoMutex lock(mLock);
636         model = mSoundModels.valueFor((SoundModelHandle)cookie);
637         if (model == 0) {
638             return Return<void>();
639         }
640     }
641     struct sound_trigger_recognition_event *event = convertRecognitionEventFromHal(&halEvent);
642     if (event == NULL) {
643         return Return<void>();
644     }
645     event->model = model->mHandle;
646     model->mRecognitionCallback(event, model->mRecognitionCookie);
647 
648     free(event);
649 
650     return Return<void>();
651 }
652 
phraseRecognitionCallback(const V2_0_ISoundTriggerHwCallback::PhraseRecognitionEvent & halEvent,CallbackCookie cookie)653 ::android::hardware::Return<void> SoundTriggerHalHidl::phraseRecognitionCallback(
654         const V2_0_ISoundTriggerHwCallback::PhraseRecognitionEvent& halEvent,
655         CallbackCookie cookie)
656 {
657     sp<SoundModel> model;
658     {
659         AutoMutex lock(mLock);
660         model = mSoundModels.valueFor((SoundModelHandle)cookie);
661         if (model == 0) {
662             return Return<void>();
663         }
664     }
665 
666     struct sound_trigger_phrase_recognition_event *event =
667             convertPhraseRecognitionEventFromHal(&halEvent);
668     if (event == NULL) {
669         return Return<void>();
670     }
671     event->common.model = model->mHandle;
672     model->mRecognitionCallback(&event->common, model->mRecognitionCookie);
673 
674     free(event);
675 
676     return Return<void>();
677 }
678 
soundModelCallback(const V2_0_ISoundTriggerHwCallback::ModelEvent & halEvent,CallbackCookie cookie)679 ::android::hardware::Return<void> SoundTriggerHalHidl::soundModelCallback(
680         const V2_0_ISoundTriggerHwCallback::ModelEvent& halEvent,
681         CallbackCookie cookie)
682 {
683     sp<SoundModel> model;
684     {
685         AutoMutex lock(mLock);
686         model = mSoundModels.valueFor((SoundModelHandle)cookie);
687         if (model == 0) {
688             return Return<void>();
689         }
690     }
691 
692     struct sound_trigger_model_event *event = convertSoundModelEventFromHal(&halEvent);
693     if (event == NULL) {
694         return Return<void>();
695     }
696 
697     event->model = model->mHandle;
698     model->mSoundModelCallback(event, model->mSoundModelCookie);
699 
700     free(event);
701 
702     return Return<void>();
703 }
704 
recognitionCallback_2_1(const ISoundTriggerHwCallback::RecognitionEvent & event,CallbackCookie cookie)705 ::android::hardware::Return<void> SoundTriggerHalHidl::recognitionCallback_2_1(
706         const ISoundTriggerHwCallback::RecognitionEvent& event, CallbackCookie cookie) {
707     // The data vector in the 'header' part of V2.1 structure is empty, thus copying is cheap.
708     V2_0_ISoundTriggerHwCallback::RecognitionEvent event_2_0 = event.header;
709     auto result = memoryAsVector(event.data, &event_2_0.data);
710     return result.first ? recognitionCallback(event_2_0, cookie) : Void();
711 }
712 
phraseRecognitionCallback_2_1(const ISoundTriggerHwCallback::PhraseRecognitionEvent & event,int32_t cookie)713 ::android::hardware::Return<void> SoundTriggerHalHidl::phraseRecognitionCallback_2_1(
714         const ISoundTriggerHwCallback::PhraseRecognitionEvent& event, int32_t cookie) {
715     V2_0_ISoundTriggerHwCallback::PhraseRecognitionEvent event_2_0;
716     // The data vector in the 'header' part of V2.1 structure is empty, thus copying is cheap.
717     event_2_0.common = event.common.header;
718     event_2_0.phraseExtras.setToExternal(
719             const_cast<PhraseRecognitionExtra*>(event.phraseExtras.data()),
720             event.phraseExtras.size());
721     auto result = memoryAsVector(event.common.data, &event_2_0.common.data);
722     return result.first ? phraseRecognitionCallback(event_2_0, cookie) : Void();
723 }
724 
soundModelCallback_2_1(const ISoundTriggerHwCallback::ModelEvent & event,CallbackCookie cookie)725 ::android::hardware::Return<void> SoundTriggerHalHidl::soundModelCallback_2_1(
726         const ISoundTriggerHwCallback::ModelEvent& event, CallbackCookie cookie) {
727     // The data vector in the 'header' part of V2.1 structure is empty, thus copying is cheap.
728     V2_0_ISoundTriggerHwCallback::ModelEvent event_2_0 = event.header;
729     auto result = memoryAsVector(event.data, &event_2_0.data);
730     return result.first ? soundModelCallback(event_2_0, cookie) : Void();
731 }
732 
733 
convertSoundModelEventFromHal(const V2_0_ISoundTriggerHwCallback::ModelEvent * halEvent)734 struct sound_trigger_model_event *SoundTriggerHalHidl::convertSoundModelEventFromHal(
735                                               const V2_0_ISoundTriggerHwCallback::ModelEvent *halEvent)
736 {
737     struct sound_trigger_model_event *event = (struct sound_trigger_model_event *)malloc(
738             sizeof(struct sound_trigger_model_event) +
739             halEvent->data.size());
740     if (event == NULL) {
741         return NULL;
742     }
743 
744     event->status = (int)halEvent->status;
745     // event->model to be set by caller
746     event->data_offset = sizeof(struct sound_trigger_model_event);
747     event->data_size = halEvent->data.size();
748     uint8_t *dst = (uint8_t *)event + event->data_offset;
749     uint8_t *src = (uint8_t *)&halEvent->data[0];
750     memcpy(dst, src, halEvent->data.size());
751 
752     return event;
753 }
754 
convertPhraseRecognitionExtraFromHal(struct sound_trigger_phrase_recognition_extra * extra,const PhraseRecognitionExtra * halExtra)755 void SoundTriggerHalHidl::convertPhraseRecognitionExtraFromHal(
756         struct sound_trigger_phrase_recognition_extra *extra,
757         const PhraseRecognitionExtra *halExtra)
758 {
759     extra->id = halExtra->id;
760     extra->recognition_modes = halExtra->recognitionModes;
761     extra->confidence_level = halExtra->confidenceLevel;
762 
763     size_t i;
764     for (i = 0; i < halExtra->levels.size() && i < SOUND_TRIGGER_MAX_USERS; i++) {
765         extra->levels[i].user_id = halExtra->levels[i].userId;
766         extra->levels[i].level = halExtra->levels[i].levelPercent;
767     }
768     extra->num_levels = (unsigned int)i;
769 }
770 
771 
convertPhraseRecognitionEventFromHal(const V2_0_ISoundTriggerHwCallback::PhraseRecognitionEvent * halPhraseEvent)772 struct sound_trigger_phrase_recognition_event* SoundTriggerHalHidl::convertPhraseRecognitionEventFromHal(
773         const V2_0_ISoundTriggerHwCallback::PhraseRecognitionEvent *halPhraseEvent)
774 {
775     if (halPhraseEvent->common.type != SoundModelType::KEYPHRASE) {
776         ALOGE("Received non-keyphrase event type as PhraseRecognitionEvent");
777         return NULL;
778     }
779     struct sound_trigger_phrase_recognition_event *phraseEvent =
780             (struct sound_trigger_phrase_recognition_event *)malloc(
781                     sizeof(struct sound_trigger_phrase_recognition_event) +
782                     halPhraseEvent->common.data.size());
783     if (phraseEvent == NULL) {
784         return NULL;
785     }
786     phraseEvent->common.data_offset = sizeof(sound_trigger_phrase_recognition_event);
787 
788     for (unsigned int i = 0; i < halPhraseEvent->phraseExtras.size(); i++) {
789         convertPhraseRecognitionExtraFromHal(&phraseEvent->phrase_extras[i],
790                                              &halPhraseEvent->phraseExtras[i]);
791     }
792     phraseEvent->num_phrases = halPhraseEvent->phraseExtras.size();
793 
794     fillRecognitionEventFromHal(&phraseEvent->common, &halPhraseEvent->common);
795     return phraseEvent;
796 }
797 
convertRecognitionEventFromHal(const V2_0_ISoundTriggerHwCallback::RecognitionEvent * halEvent)798 struct sound_trigger_recognition_event *SoundTriggerHalHidl::convertRecognitionEventFromHal(
799         const V2_0_ISoundTriggerHwCallback::RecognitionEvent *halEvent)
800 {
801     if (halEvent->type == SoundModelType::KEYPHRASE) {
802         ALOGE("Received keyphrase event type as RecognitionEvent");
803         return NULL;
804     }
805     struct sound_trigger_recognition_event *event;
806     event = (struct sound_trigger_recognition_event *)malloc(
807             sizeof(struct sound_trigger_recognition_event) + halEvent->data.size());
808     if (event == NULL) {
809         return NULL;
810     }
811     event->data_offset = sizeof(sound_trigger_recognition_event);
812 
813     fillRecognitionEventFromHal(event, halEvent);
814     return event;
815 }
816 
fillRecognitionEventFromHal(struct sound_trigger_recognition_event * event,const V2_0_ISoundTriggerHwCallback::RecognitionEvent * halEvent)817 void SoundTriggerHalHidl::fillRecognitionEventFromHal(
818         struct sound_trigger_recognition_event *event,
819         const V2_0_ISoundTriggerHwCallback::RecognitionEvent *halEvent)
820 {
821     event->status = (int)halEvent->status;
822     event->type = (sound_trigger_sound_model_type_t)halEvent->type;
823     // event->model to be set by caller
824     event->capture_available = (bool)halEvent->captureAvailable;
825     event->capture_session = halEvent->captureSession;
826     event->capture_delay_ms = halEvent->captureDelayMs;
827     event->capture_preamble_ms = halEvent->capturePreambleMs;
828     event->trigger_in_data = (bool)halEvent->triggerInData;
829     event->audio_config.sample_rate = halEvent->audioConfig.sampleRateHz;
830     event->audio_config.channel_mask = (audio_channel_mask_t)halEvent->audioConfig.channelMask;
831     event->audio_config.format = (audio_format_t)halEvent->audioConfig.format;
832 
833     event->data_size = halEvent->data.size();
834     uint8_t *dst = (uint8_t *)event + event->data_offset;
835     uint8_t *src = (uint8_t *)&halEvent->data[0];
836     memcpy(dst, src, halEvent->data.size());
837 }
838 
839 } // namespace android
840