blob: c0277995434573c75195179da22c6a13ebd64d43 [file] [log] [blame]
Eric Laurent7a544b42016-08-05 19:01:13 -07001/*
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 <utils/Log.h>
21#include "SoundTriggerHalHidl.h"
Eric Laurent7a544b42016-08-05 19:01:13 -070022#include <hwbinder/IPCThreadState.h>
23#include <hwbinder/ProcessState.h>
24
25namespace android {
26
27using android::hardware::Return;
28using android::hardware::ProcessState;
29using android::hardware::audio::common::V2_0::AudioDevice;
30
Eric Laurent7a544b42016-08-05 19:01:13 -070031/* static */
32sp<SoundTriggerHalInterface> SoundTriggerHalInterface::connectModule(const char *moduleName)
33{
34 return new SoundTriggerHalHidl(moduleName);
35}
36
37int SoundTriggerHalHidl::getProperties(struct sound_trigger_properties *properties)
38{
39 sp<ISoundTriggerHw> soundtrigger = getService();
40 if (soundtrigger == 0) {
41 return -ENODEV;
42 }
43
44 ISoundTriggerHw::Properties halProperties;
45 Return<void> hidlReturn;
Eric Laurent4b38e7a2016-11-11 13:28:53 -080046 int ret;
Eric Laurent7a544b42016-08-05 19:01:13 -070047 {
48 AutoMutex lock(mHalLock);
49 hidlReturn = soundtrigger->getProperties([&](int rc, auto res) {
Eric Laurent4b38e7a2016-11-11 13:28:53 -080050 ret = rc;
Eric Laurent7a544b42016-08-05 19:01:13 -070051 halProperties = res;
52 ALOGI("getProperties res implementor %s", res.implementor.c_str());
53 });
54 }
55
Eric Laurent7a544b42016-08-05 19:01:13 -070056 if (hidlReturn.getStatus().isOk()) {
Eric Laurent4b38e7a2016-11-11 13:28:53 -080057 if (ret == 0) {
58 convertPropertiesFromHal(properties, &halProperties);
59 }
Eric Laurent7a544b42016-08-05 19:01:13 -070060 } else {
61 ret = (int)hidlReturn.getStatus().transactionError();
Mikhail Naganov9f57e3c2016-12-05 12:54:36 -080062 crashIfHalIsDead(ret);
Eric Laurent7a544b42016-08-05 19:01:13 -070063 }
Eric Laurent4b38e7a2016-11-11 13:28:53 -080064 ALOGI("getProperties ret %d", ret);
Eric Laurent7a544b42016-08-05 19:01:13 -070065 return ret;
66}
67
68int SoundTriggerHalHidl::loadSoundModel(struct sound_trigger_sound_model *sound_model,
69 sound_model_callback_t callback,
70 void *cookie,
71 sound_model_handle_t *handle)
72{
73 if (handle == NULL) {
74 return -EINVAL;
75 }
76
77 sp<ISoundTriggerHw> soundtrigger = getService();
78 if (soundtrigger == 0) {
79 return -ENODEV;
80 }
81
82 uint32_t modelId;
83 {
84 AutoMutex lock(mLock);
85 do {
86 modelId = nextUniqueId();
87 ALOGI("loadSoundModel modelId %u", modelId);
88 sp<SoundModel> model = mSoundModels.valueFor(modelId);
89 ALOGI("loadSoundModel model %p", model.get());
90 } while (mSoundModels.valueFor(modelId) != 0 && modelId != 0);
91 }
92 LOG_ALWAYS_FATAL_IF(modelId == 0,
93 "loadSoundModel(): wrap around in sound model IDs, num loaded models %zd",
94 mSoundModels.size());
95
96 ISoundTriggerHw::SoundModel *halSoundModel =
97 convertSoundModelToHal(sound_model);
98 if (halSoundModel == NULL) {
99 return -EINVAL;
100 }
101
102 Return<void> hidlReturn;
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800103 int ret;
Eric Laurent7a544b42016-08-05 19:01:13 -0700104 SoundModelHandle halHandle;
105 {
106 AutoMutex lock(mHalLock);
107 if (sound_model->type == SOUND_MODEL_TYPE_KEYPHRASE) {
108 hidlReturn = soundtrigger->loadPhraseSoundModel(
109 *(const ISoundTriggerHw::PhraseSoundModel *)halSoundModel,
110 this, modelId, [&](int32_t retval, auto res) {
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800111 ret = retval;
Eric Laurent7a544b42016-08-05 19:01:13 -0700112 halHandle = res;
113 });
114
115 } else {
116 hidlReturn = soundtrigger->loadSoundModel(*halSoundModel,
117 this, modelId, [&](int32_t retval, auto res) {
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800118 ret = retval;
Eric Laurent7a544b42016-08-05 19:01:13 -0700119 halHandle = res;
120 });
121 }
122 }
123
124 delete halSoundModel;
125
Eric Laurent7a544b42016-08-05 19:01:13 -0700126 if (hidlReturn.getStatus().isOk()) {
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800127 if (ret == 0) {
128 AutoMutex lock(mLock);
129 *handle = (sound_model_handle_t)modelId;
130 sp<SoundModel> model = new SoundModel(*handle, callback, cookie, halHandle);
131 mSoundModels.add(*handle, model);
132 }
Eric Laurent7a544b42016-08-05 19:01:13 -0700133 } else {
134 ret = (int)hidlReturn.getStatus().transactionError();
135 ALOGE("loadSoundModel error %d", ret);
Mikhail Naganov9f57e3c2016-12-05 12:54:36 -0800136 crashIfHalIsDead(ret);
Eric Laurent7a544b42016-08-05 19:01:13 -0700137 }
138
139
140 return ret;
141}
142
143int SoundTriggerHalHidl::unloadSoundModel(sound_model_handle_t handle)
144{
145 sp<ISoundTriggerHw> soundtrigger = getService();
146 if (soundtrigger == 0) {
147 return -ENODEV;
148 }
149
150 sp<SoundModel> model = removeModel(handle);
151 if (model == 0) {
152 ALOGE("unloadSoundModel model not found for handle %u", handle);
153 return -EINVAL;
154 }
155
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800156 Return<int32_t> hidlReturn(0);
Eric Laurent7a544b42016-08-05 19:01:13 -0700157 {
158 AutoMutex lock(mHalLock);
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800159 hidlReturn = soundtrigger->unloadSoundModel(model->mHalHandle);
Eric Laurent7a544b42016-08-05 19:01:13 -0700160 }
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800161 int ret = (int)hidlReturn.getStatus().transactionError();
Eric Laurent7a544b42016-08-05 19:01:13 -0700162 ALOGE_IF(ret != 0, "unloadSoundModel error %d", ret);
Mikhail Naganov9f57e3c2016-12-05 12:54:36 -0800163 crashIfHalIsDead(ret);
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800164 if (ret == 0) {
165 ret = hidlReturn;
166 }
Eric Laurent7a544b42016-08-05 19:01:13 -0700167 return ret;
168}
169
170int SoundTriggerHalHidl::startRecognition(sound_model_handle_t handle,
171 const struct sound_trigger_recognition_config *config,
172 recognition_callback_t callback,
173 void *cookie)
174{
175 sp<ISoundTriggerHw> soundtrigger = getService();
176 if (soundtrigger == 0) {
177 return -ENODEV;
178 }
179
180 sp<SoundModel> model = getModel(handle);
181 if (model == 0) {
182 ALOGE("startRecognition model not found for handle %u", handle);
183 return -EINVAL;
184 }
185
186 model->mRecognitionCallback = callback;
187 model->mRecognitionCookie = cookie;
188
189 ISoundTriggerHw::RecognitionConfig *halConfig =
190 convertRecognitionConfigToHal(config);
191
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800192 Return<int32_t> hidlReturn(0);
Eric Laurent7a544b42016-08-05 19:01:13 -0700193 {
194 AutoMutex lock(mHalLock);
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800195 hidlReturn = soundtrigger->startRecognition(model->mHalHandle, *halConfig, this, handle);
Eric Laurent7a544b42016-08-05 19:01:13 -0700196 }
197
198 delete halConfig;
199
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800200 int ret = (int)hidlReturn.getStatus().transactionError();
Eric Laurent7a544b42016-08-05 19:01:13 -0700201 ALOGE_IF(ret != 0, "startRecognition error %d", ret);
Mikhail Naganov9f57e3c2016-12-05 12:54:36 -0800202 crashIfHalIsDead(ret);
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800203 if (ret == 0) {
204 ret = hidlReturn;
205 }
Eric Laurent7a544b42016-08-05 19:01:13 -0700206 return ret;
207}
208
209int SoundTriggerHalHidl::stopRecognition(sound_model_handle_t handle)
210{
211 sp<ISoundTriggerHw> soundtrigger = getService();
212 if (soundtrigger == 0) {
213 return -ENODEV;
214 }
215
216 sp<SoundModel> model = getModel(handle);
217 if (model == 0) {
218 ALOGE("stopRecognition model not found for handle %u", handle);
219 return -EINVAL;
220 }
221
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800222 Return<int32_t> hidlReturn(0);
Eric Laurent7a544b42016-08-05 19:01:13 -0700223 {
224 AutoMutex lock(mHalLock);
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800225 hidlReturn = soundtrigger->stopRecognition(model->mHalHandle);
Eric Laurent7a544b42016-08-05 19:01:13 -0700226 }
227
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800228 int ret = (int)hidlReturn.getStatus().transactionError();
Eric Laurent7a544b42016-08-05 19:01:13 -0700229 ALOGE_IF(ret != 0, "stopRecognition error %d", ret);
Mikhail Naganov9f57e3c2016-12-05 12:54:36 -0800230 crashIfHalIsDead(ret);
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800231 if (ret == 0) {
232 ret = hidlReturn;
233 }
Eric Laurent7a544b42016-08-05 19:01:13 -0700234 return ret;
235}
236
237int SoundTriggerHalHidl::stopAllRecognitions()
238{
239 sp<ISoundTriggerHw> soundtrigger = getService();
240 if (soundtrigger == 0) {
241 return -ENODEV;
242 }
243
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800244 Return<int32_t> hidlReturn(0);
Eric Laurent7a544b42016-08-05 19:01:13 -0700245 {
246 AutoMutex lock(mHalLock);
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800247 hidlReturn = soundtrigger->stopAllRecognitions();
Eric Laurent7a544b42016-08-05 19:01:13 -0700248 }
249
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800250 int ret = (int)hidlReturn.getStatus().transactionError();
Eric Laurent7a544b42016-08-05 19:01:13 -0700251 ALOGE_IF(ret != 0, "stopAllRecognitions error %d", ret);
Mikhail Naganov9f57e3c2016-12-05 12:54:36 -0800252 crashIfHalIsDead(ret);
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800253 if (ret == 0) {
254 ret = hidlReturn;
255 }
Eric Laurent7a544b42016-08-05 19:01:13 -0700256 return ret;
257}
258
259SoundTriggerHalHidl::SoundTriggerHalHidl(const char *moduleName)
260 : mModuleName(moduleName), mNextUniqueId(1)
261{
262}
263
Eric Laurent7a544b42016-08-05 19:01:13 -0700264SoundTriggerHalHidl::~SoundTriggerHalHidl()
265{
266}
267
268sp<ISoundTriggerHw> SoundTriggerHalHidl::getService()
269{
270 AutoMutex lock(mLock);
271 if (mISoundTrigger == 0) {
272 if (mModuleName == NULL) {
273 mModuleName = "primary";
274 }
275 std::string serviceName = "sound_trigger.";
276 serviceName.append(mModuleName);
277 mISoundTrigger = ISoundTriggerHw::getService(serviceName);
278 }
279 return mISoundTrigger;
280}
281
Mikhail Naganov9f57e3c2016-12-05 12:54:36 -0800282void SoundTriggerHalHidl::crashIfHalIsDead(int ret)
Eric Laurent7a544b42016-08-05 19:01:13 -0700283{
Mikhail Naganov9f57e3c2016-12-05 12:54:36 -0800284 LOG_ALWAYS_FATAL_IF(ret == -EPIPE, "HAL server crashed, need to restart");
Eric Laurent7a544b42016-08-05 19:01:13 -0700285}
286
287sp<SoundTriggerHalHidl::SoundModel> SoundTriggerHalHidl::getModel(sound_model_handle_t handle)
288{
289 AutoMutex lock(mLock);
290 return mSoundModels.valueFor(handle);
291}
292
293sp<SoundTriggerHalHidl::SoundModel> SoundTriggerHalHidl::removeModel(sound_model_handle_t handle)
294{
295 AutoMutex lock(mLock);
296 sp<SoundModel> model = mSoundModels.valueFor(handle);
297 mSoundModels.removeItem(handle);
298 return model;
299}
300
301uint32_t SoundTriggerHalHidl::nextUniqueId()
302{
303 return (uint32_t) atomic_fetch_add_explicit(&mNextUniqueId,
304 (uint_fast32_t) 1, memory_order_acq_rel);
305}
306
307void SoundTriggerHalHidl::convertUuidToHal(Uuid *halUuid,
Eric Laurentf7854d42016-10-14 15:57:18 -0700308 const sound_trigger_uuid_t *uuid)
Eric Laurent7a544b42016-08-05 19:01:13 -0700309{
310 halUuid->timeLow = uuid->timeLow;
311 halUuid->timeMid = uuid->timeMid;
312 halUuid->versionAndTimeHigh = uuid->timeHiAndVersion;
313 halUuid->variantAndClockSeqHigh = uuid->clockSeq;
314 memcpy(halUuid->node.data(), &uuid->node[0], sizeof(uuid->node));
315}
316
Eric Laurentf7854d42016-10-14 15:57:18 -0700317void SoundTriggerHalHidl::convertUuidFromHal(sound_trigger_uuid_t *uuid,
Eric Laurent7a544b42016-08-05 19:01:13 -0700318 const Uuid *halUuid)
319{
320 uuid->timeLow = halUuid->timeLow;
321 uuid->timeMid = halUuid->timeMid;
322 uuid->timeHiAndVersion = halUuid->versionAndTimeHigh;
323 uuid->clockSeq = halUuid->variantAndClockSeqHigh;
324 memcpy(&uuid->node[0], halUuid->node.data(), sizeof(uuid->node));
325}
326
327void SoundTriggerHalHidl::convertPropertiesFromHal(
328 struct sound_trigger_properties *properties,
329 const ISoundTriggerHw::Properties *halProperties)
330{
331 strlcpy(properties->implementor,
332 halProperties->implementor.c_str(), SOUND_TRIGGER_MAX_STRING_LEN);
333 strlcpy(properties->description,
334 halProperties->description.c_str(), SOUND_TRIGGER_MAX_STRING_LEN);
335 properties->version = halProperties->version;
336 convertUuidFromHal(&properties->uuid, &halProperties->uuid);
337 properties->max_sound_models = halProperties->maxSoundModels;
338 properties->max_key_phrases = halProperties->maxKeyPhrases;
339 properties->max_users = halProperties->maxUsers;
340 properties->recognition_modes = halProperties->recognitionModes;
341 properties->capture_transition = (bool)halProperties->captureTransition;
342 properties->max_buffer_ms = halProperties->maxBufferMs;
343 properties->concurrent_capture = (bool)halProperties->concurrentCapture;
344 properties->trigger_in_event = (bool)halProperties->triggerInEvent;
345 properties->power_consumption_mw = halProperties->powerConsumptionMw;
346}
347
348void SoundTriggerHalHidl::convertTriggerPhraseToHal(
349 ISoundTriggerHw::Phrase *halTriggerPhrase,
350 const struct sound_trigger_phrase *triggerPhrase)
351{
352 halTriggerPhrase->id = triggerPhrase->id;
353 halTriggerPhrase->recognitionModes = triggerPhrase->recognition_mode;
354 halTriggerPhrase->users.setToExternal((uint32_t *)&triggerPhrase->users[0], triggerPhrase->num_users);
355 halTriggerPhrase->locale = triggerPhrase->locale;
356 halTriggerPhrase->text = triggerPhrase->text;
357}
358
359ISoundTriggerHw::SoundModel *SoundTriggerHalHidl::convertSoundModelToHal(
360 const struct sound_trigger_sound_model *soundModel)
361{
362 ISoundTriggerHw::SoundModel *halModel = NULL;
363 if (soundModel->type == SOUND_MODEL_TYPE_KEYPHRASE) {
364 ISoundTriggerHw::PhraseSoundModel *halKeyPhraseModel =
365 new ISoundTriggerHw::PhraseSoundModel();
366 struct sound_trigger_phrase_sound_model *keyPhraseModel =
367 (struct sound_trigger_phrase_sound_model *)soundModel;
368 ISoundTriggerHw::Phrase *halPhrases =
369 new ISoundTriggerHw::Phrase[keyPhraseModel->num_phrases];
370
371
372 for (unsigned int i = 0; i < keyPhraseModel->num_phrases; i++) {
373 convertTriggerPhraseToHal(&halPhrases[i],
374 &keyPhraseModel->phrases[i]);
375 }
376 halKeyPhraseModel->phrases.setToExternal(halPhrases, keyPhraseModel->num_phrases);
377 // FIXME: transfer buffer ownership. should have a method for that in hidl_vec
378 halKeyPhraseModel->phrases.resize(keyPhraseModel->num_phrases);
379
380 delete[] halPhrases;
381
382 halModel = (ISoundTriggerHw::SoundModel *)halKeyPhraseModel;
383 } else {
384 halModel = new ISoundTriggerHw::SoundModel();
385 }
386 halModel->type = (SoundModelType)soundModel->type;
387 convertUuidToHal(&halModel->uuid, &soundModel->uuid);
388 convertUuidToHal(&halModel->vendorUuid, &soundModel->vendor_uuid);
389 halModel->data.setToExternal((uint8_t *)soundModel + soundModel->data_offset, soundModel->data_size);
390 halModel->data.resize(soundModel->data_size);
391
392 return halModel;
393}
394
395void SoundTriggerHalHidl::convertPhraseRecognitionExtraToHal(
396 PhraseRecognitionExtra *halExtra,
397 const struct sound_trigger_phrase_recognition_extra *extra)
398{
399 halExtra->id = extra->id;
400 halExtra->recognitionModes = extra->recognition_modes;
401 halExtra->confidenceLevel = extra->confidence_level;
402 ConfidenceLevel *halLevels =
403 new ConfidenceLevel[extra->num_levels];
404 for (unsigned int i = 0; i < extra->num_levels; i++) {
405 halLevels[i].userId = extra->levels[i].user_id;
406 halLevels[i].levelPercent = extra->levels[i].level;
407 }
408 halExtra->levels.setToExternal(halLevels, extra->num_levels);
409 // FIXME: transfer buffer ownership. should have a method for that in hidl_vec
410 halExtra->levels.resize(extra->num_levels);
411
412 delete[] halLevels;
413}
414
415
416ISoundTriggerHw::RecognitionConfig *SoundTriggerHalHidl::convertRecognitionConfigToHal(
417 const struct sound_trigger_recognition_config *config)
418{
419 ISoundTriggerHw::RecognitionConfig *halConfig =
420 new ISoundTriggerHw::RecognitionConfig();
421
422 halConfig->captureHandle = config->capture_handle;
423 halConfig->captureDevice = (AudioDevice)config->capture_device;
424 halConfig->captureRequested = (uint32_t)config->capture_requested;
425
426 PhraseRecognitionExtra *halExtras =
427 new PhraseRecognitionExtra[config->num_phrases];
428
429 for (unsigned int i = 0; i < config->num_phrases; i++) {
430 convertPhraseRecognitionExtraToHal(&halExtras[i],
431 &config->phrases[i]);
432 }
433 halConfig->phrases.setToExternal(halExtras, config->num_phrases);
434 // FIXME: transfer buffer ownership. should have a method for that in hidl_vec
435 halConfig->phrases.resize(config->num_phrases);
436
437 delete[] halExtras;
438
439 halConfig->data.setToExternal((uint8_t *)config + config->data_offset, config->data_size);
440
441 return halConfig;
442}
443
444
445// ISoundTriggerHwCallback
446::android::hardware::Return<void> SoundTriggerHalHidl::recognitionCallback(
447 const ISoundTriggerHwCallback::RecognitionEvent& halEvent,
448 CallbackCookie cookie)
449{
450 sp<SoundModel> model;
451 {
452 AutoMutex lock(mLock);
453 model = mSoundModels.valueFor((SoundModelHandle)cookie);
454 if (model == 0) {
455 return Return<void>();
456 }
457 }
458 struct sound_trigger_recognition_event *event = convertRecognitionEventFromHal(&halEvent);
459 if (event == NULL) {
460 return Return<void>();
461 }
462 event->model = model->mHandle;
463 model->mRecognitionCallback(event, model->mRecognitionCookie);
464
465 free(event);
466
467 return Return<void>();
468}
469
470::android::hardware::Return<void> SoundTriggerHalHidl::phraseRecognitionCallback(
471 const ISoundTriggerHwCallback::PhraseRecognitionEvent& halEvent,
472 CallbackCookie cookie)
473{
474 sp<SoundModel> model;
475 {
476 AutoMutex lock(mLock);
477 model = mSoundModels.valueFor((SoundModelHandle)cookie);
478 if (model == 0) {
479 return Return<void>();
480 }
481 }
482
483 struct sound_trigger_recognition_event *event = convertRecognitionEventFromHal(
484 (const ISoundTriggerHwCallback::RecognitionEvent *)&halEvent);
485 if (event == NULL) {
486 return Return<void>();
487 }
488
489 event->model = model->mHandle;
490 model->mRecognitionCallback(event, model->mRecognitionCookie);
491
492 free(event);
493
494 return Return<void>();
495}
496
497::android::hardware::Return<void> SoundTriggerHalHidl::soundModelCallback(
498 const ISoundTriggerHwCallback::ModelEvent& halEvent,
499 CallbackCookie cookie)
500{
501 sp<SoundModel> model;
502 {
503 AutoMutex lock(mLock);
504 model = mSoundModels.valueFor((SoundModelHandle)cookie);
505 if (model == 0) {
506 return Return<void>();
507 }
508 }
509
510 struct sound_trigger_model_event *event = convertSoundModelEventFromHal(&halEvent);
511 if (event == NULL) {
512 return Return<void>();
513 }
514
515 event->model = model->mHandle;
516 model->mSoundModelCallback(event, model->mSoundModelCookie);
517
518 free(event);
519
520 return Return<void>();
521}
522
523
524struct sound_trigger_model_event *SoundTriggerHalHidl::convertSoundModelEventFromHal(
525 const ISoundTriggerHwCallback::ModelEvent *halEvent)
526{
527 struct sound_trigger_model_event *event = (struct sound_trigger_model_event *)malloc(
528 sizeof(struct sound_trigger_model_event) +
529 halEvent->data.size());
530 if (event == NULL) {
531 return NULL;
532 }
533
534 event->status = (int)halEvent->status;
535 // event->model to be set by caller
536 event->data_offset = sizeof(struct sound_trigger_model_event);
537 event->data_size = halEvent->data.size();
538 uint8_t *dst = (uint8_t *)event + event->data_offset;
539 uint8_t *src = (uint8_t *)&halEvent->data[0];
540 memcpy(dst, src, halEvent->data.size());
541
542 return event;
543}
544
545void SoundTriggerHalHidl::convertPhraseRecognitionExtraFromHal(
546 struct sound_trigger_phrase_recognition_extra *extra,
547 const PhraseRecognitionExtra *halExtra)
548{
549 extra->id = halExtra->id;
550 extra->recognition_modes = halExtra->recognitionModes;
551 extra->confidence_level = halExtra->confidenceLevel;
552
553 size_t i;
554 for (i = 0; i < halExtra->levels.size() && i < SOUND_TRIGGER_MAX_USERS; i++) {
555 extra->levels[i].user_id = halExtra->levels[i].userId;
556 extra->levels[i].level = halExtra->levels[i].levelPercent;
557 }
558 extra->num_levels = (unsigned int)i;
559}
560
561
562struct sound_trigger_recognition_event *SoundTriggerHalHidl::convertRecognitionEventFromHal(
563 const ISoundTriggerHwCallback::RecognitionEvent *halEvent)
564{
565 struct sound_trigger_recognition_event *event;
566
567 if (halEvent->type == SoundModelType::KEYPHRASE) {
568 struct sound_trigger_phrase_recognition_event *phraseEvent =
569 (struct sound_trigger_phrase_recognition_event *)malloc(
570 sizeof(struct sound_trigger_phrase_recognition_event) +
571 halEvent->data.size());
572 if (phraseEvent == NULL) {
573 return NULL;
574 }
575 const ISoundTriggerHwCallback::PhraseRecognitionEvent *halPhraseEvent =
576 (const ISoundTriggerHwCallback::PhraseRecognitionEvent *)halEvent;
577
578 for (unsigned int i = 0; i < halPhraseEvent->phraseExtras.size(); i++) {
579 convertPhraseRecognitionExtraFromHal(&phraseEvent->phrase_extras[i],
580 &halPhraseEvent->phraseExtras[i]);
581 }
582 phraseEvent->num_phrases = halPhraseEvent->phraseExtras.size();
583 event = (struct sound_trigger_recognition_event *)phraseEvent;
584 event->data_offset = sizeof(sound_trigger_phrase_recognition_event);
585 } else {
586 event = (struct sound_trigger_recognition_event *)malloc(
587 sizeof(struct sound_trigger_recognition_event) + halEvent->data.size());
588 if (event == NULL) {
589 return NULL;
590 }
591 event->data_offset = sizeof(sound_trigger_recognition_event);
592 }
593 event->status = (int)halEvent->status;
594 event->type = (sound_trigger_sound_model_type_t)halEvent->type;
595 // event->model to be set by caller
596 event->capture_available = (bool)halEvent->captureAvailable;
597 event->capture_session = halEvent->captureSession;
598 event->capture_delay_ms = halEvent->captureDelayMs;
599 event->capture_preamble_ms = halEvent->capturePreambleMs;
600 event->trigger_in_data = (bool)halEvent->triggerInData;
601 event->audio_config.sample_rate = halEvent->audioConfig.sampleRateHz;
602 event->audio_config.channel_mask = (audio_channel_mask_t)halEvent->audioConfig.channelMask;
603 event->audio_config.format = (audio_format_t)halEvent->audioConfig.format;
604
605 event->data_size = halEvent->data.size();
606 uint8_t *dst = (uint8_t *)event + event->data_offset;
607 uint8_t *src = (uint8_t *)&halEvent->data[0];
608 memcpy(dst, src, halEvent->data.size());
609
610 return event;
611}
612
613} // namespace android