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 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 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 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 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 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 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 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 437 SoundTriggerHalHidl::~SoundTriggerHalHidl() 438 { 439 } 440 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 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 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 468 sp<SoundTriggerHalHidl::SoundModel> SoundTriggerHalHidl::getModel(sound_model_handle_t handle) 469 { 470 AutoMutex lock(mLock); 471 return mSoundModels.valueFor(handle); 472 } 473 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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