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. 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. 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 */ 103 sp<SoundTriggerHalInterface> SoundTriggerHalInterface::connectModule(const char *moduleName) 104 { 105 return new SoundTriggerHalHidl(moduleName); 106 } 107 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 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 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 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 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 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 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 366 SoundTriggerHalHidl::~SoundTriggerHalHidl() 367 { 368 } 369 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 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 391 sp<SoundTriggerHalHidl::SoundModel> SoundTriggerHalHidl::getModel(sound_model_handle_t handle) 392 { 393 AutoMutex lock(mLock); 394 return mSoundModels.valueFor(handle); 395 } 396 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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