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