blob: eb9d38d696806f4c3ac950a382771d0d0cc15c9d [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
Steven Morelande83be8a2017-01-06 11:06:33 -080056 if (hidlReturn.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 {
Steven Morelande83be8a2017-01-06 11:06:33 -080061 ALOGE("getProperties error %s", hidlReturn.description().c_str());
62 return UNKNOWN_ERROR;
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
Steven Morelande83be8a2017-01-06 11:06:33 -0800126 if (hidlReturn.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 {
Steven Morelande83be8a2017-01-06 11:06:33 -0800134 ALOGE("loadSoundModel error %s", hidlReturn.description().c_str());
135 return UNKNOWN_ERROR;
Eric Laurent7a544b42016-08-05 19:01:13 -0700136 }
137
Eric Laurent7a544b42016-08-05 19:01:13 -0700138 return ret;
139}
140
141int SoundTriggerHalHidl::unloadSoundModel(sound_model_handle_t handle)
142{
143 sp<ISoundTriggerHw> soundtrigger = getService();
144 if (soundtrigger == 0) {
145 return -ENODEV;
146 }
147
148 sp<SoundModel> model = removeModel(handle);
149 if (model == 0) {
150 ALOGE("unloadSoundModel model not found for handle %u", handle);
151 return -EINVAL;
152 }
153
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800154 Return<int32_t> hidlReturn(0);
Eric Laurent7a544b42016-08-05 19:01:13 -0700155 {
156 AutoMutex lock(mHalLock);
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800157 hidlReturn = soundtrigger->unloadSoundModel(model->mHalHandle);
Eric Laurent7a544b42016-08-05 19:01:13 -0700158 }
Steven Morelande83be8a2017-01-06 11:06:33 -0800159
160 if (!hidlReturn.isOk()) {
161 ALOGE("unloadSoundModel error %s", hidlReturn.description().c_str());
162 return UNKNOWN_ERROR;
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800163 }
Steven Morelande83be8a2017-01-06 11:06:33 -0800164
165 return hidlReturn;
Eric Laurent7a544b42016-08-05 19:01:13 -0700166}
167
168int SoundTriggerHalHidl::startRecognition(sound_model_handle_t handle,
169 const struct sound_trigger_recognition_config *config,
170 recognition_callback_t callback,
171 void *cookie)
172{
173 sp<ISoundTriggerHw> soundtrigger = getService();
174 if (soundtrigger == 0) {
175 return -ENODEV;
176 }
177
178 sp<SoundModel> model = getModel(handle);
179 if (model == 0) {
180 ALOGE("startRecognition model not found for handle %u", handle);
181 return -EINVAL;
182 }
183
184 model->mRecognitionCallback = callback;
185 model->mRecognitionCookie = cookie;
186
187 ISoundTriggerHw::RecognitionConfig *halConfig =
188 convertRecognitionConfigToHal(config);
189
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800190 Return<int32_t> hidlReturn(0);
Eric Laurent7a544b42016-08-05 19:01:13 -0700191 {
192 AutoMutex lock(mHalLock);
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800193 hidlReturn = soundtrigger->startRecognition(model->mHalHandle, *halConfig, this, handle);
Eric Laurent7a544b42016-08-05 19:01:13 -0700194 }
195
196 delete halConfig;
197
Steven Morelande83be8a2017-01-06 11:06:33 -0800198 if (!hidlReturn.isOk()) {
199 ALOGE("startRecognition error %s", hidlReturn.description().c_str());
200 return UNKNOWN_ERROR;
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800201 }
Steven Morelande83be8a2017-01-06 11:06:33 -0800202 return hidlReturn;
Eric Laurent7a544b42016-08-05 19:01:13 -0700203}
204
205int SoundTriggerHalHidl::stopRecognition(sound_model_handle_t handle)
206{
207 sp<ISoundTriggerHw> soundtrigger = getService();
208 if (soundtrigger == 0) {
209 return -ENODEV;
210 }
211
212 sp<SoundModel> model = getModel(handle);
213 if (model == 0) {
214 ALOGE("stopRecognition model not found for handle %u", handle);
215 return -EINVAL;
216 }
217
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800218 Return<int32_t> hidlReturn(0);
Eric Laurent7a544b42016-08-05 19:01:13 -0700219 {
220 AutoMutex lock(mHalLock);
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800221 hidlReturn = soundtrigger->stopRecognition(model->mHalHandle);
Eric Laurent7a544b42016-08-05 19:01:13 -0700222 }
223
Steven Morelande83be8a2017-01-06 11:06:33 -0800224 if (!hidlReturn.isOk()) {
225 ALOGE("stopRecognition error %s", hidlReturn.description().c_str());
226 return UNKNOWN_ERROR;
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800227 }
Steven Morelande83be8a2017-01-06 11:06:33 -0800228 return hidlReturn;
Eric Laurent7a544b42016-08-05 19:01:13 -0700229}
230
231int SoundTriggerHalHidl::stopAllRecognitions()
232{
233 sp<ISoundTriggerHw> soundtrigger = getService();
234 if (soundtrigger == 0) {
235 return -ENODEV;
236 }
237
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800238 Return<int32_t> hidlReturn(0);
Eric Laurent7a544b42016-08-05 19:01:13 -0700239 {
240 AutoMutex lock(mHalLock);
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800241 hidlReturn = soundtrigger->stopAllRecognitions();
Eric Laurent7a544b42016-08-05 19:01:13 -0700242 }
243
Steven Morelande83be8a2017-01-06 11:06:33 -0800244 if (!hidlReturn.isOk()) {
245 ALOGE("stopAllRecognitions error %s", hidlReturn.description().c_str());
246 return UNKNOWN_ERROR;
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800247 }
Steven Morelande83be8a2017-01-06 11:06:33 -0800248 return hidlReturn;
Eric Laurent7a544b42016-08-05 19:01:13 -0700249}
250
251SoundTriggerHalHidl::SoundTriggerHalHidl(const char *moduleName)
252 : mModuleName(moduleName), mNextUniqueId(1)
253{
254}
255
Eric Laurent7a544b42016-08-05 19:01:13 -0700256SoundTriggerHalHidl::~SoundTriggerHalHidl()
257{
258}
259
260sp<ISoundTriggerHw> SoundTriggerHalHidl::getService()
261{
262 AutoMutex lock(mLock);
263 if (mISoundTrigger == 0) {
264 if (mModuleName == NULL) {
265 mModuleName = "primary";
266 }
267 std::string serviceName = "sound_trigger.";
268 serviceName.append(mModuleName);
269 mISoundTrigger = ISoundTriggerHw::getService(serviceName);
270 }
271 return mISoundTrigger;
272}
273
Eric Laurent7a544b42016-08-05 19:01:13 -0700274sp<SoundTriggerHalHidl::SoundModel> SoundTriggerHalHidl::getModel(sound_model_handle_t handle)
275{
276 AutoMutex lock(mLock);
277 return mSoundModels.valueFor(handle);
278}
279
280sp<SoundTriggerHalHidl::SoundModel> SoundTriggerHalHidl::removeModel(sound_model_handle_t handle)
281{
282 AutoMutex lock(mLock);
283 sp<SoundModel> model = mSoundModels.valueFor(handle);
284 mSoundModels.removeItem(handle);
285 return model;
286}
287
288uint32_t SoundTriggerHalHidl::nextUniqueId()
289{
290 return (uint32_t) atomic_fetch_add_explicit(&mNextUniqueId,
291 (uint_fast32_t) 1, memory_order_acq_rel);
292}
293
294void SoundTriggerHalHidl::convertUuidToHal(Uuid *halUuid,
Eric Laurentf7854d42016-10-14 15:57:18 -0700295 const sound_trigger_uuid_t *uuid)
Eric Laurent7a544b42016-08-05 19:01:13 -0700296{
297 halUuid->timeLow = uuid->timeLow;
298 halUuid->timeMid = uuid->timeMid;
299 halUuid->versionAndTimeHigh = uuid->timeHiAndVersion;
300 halUuid->variantAndClockSeqHigh = uuid->clockSeq;
301 memcpy(halUuid->node.data(), &uuid->node[0], sizeof(uuid->node));
302}
303
Eric Laurentf7854d42016-10-14 15:57:18 -0700304void SoundTriggerHalHidl::convertUuidFromHal(sound_trigger_uuid_t *uuid,
Eric Laurent7a544b42016-08-05 19:01:13 -0700305 const Uuid *halUuid)
306{
307 uuid->timeLow = halUuid->timeLow;
308 uuid->timeMid = halUuid->timeMid;
309 uuid->timeHiAndVersion = halUuid->versionAndTimeHigh;
310 uuid->clockSeq = halUuid->variantAndClockSeqHigh;
311 memcpy(&uuid->node[0], halUuid->node.data(), sizeof(uuid->node));
312}
313
314void SoundTriggerHalHidl::convertPropertiesFromHal(
315 struct sound_trigger_properties *properties,
316 const ISoundTriggerHw::Properties *halProperties)
317{
318 strlcpy(properties->implementor,
319 halProperties->implementor.c_str(), SOUND_TRIGGER_MAX_STRING_LEN);
320 strlcpy(properties->description,
321 halProperties->description.c_str(), SOUND_TRIGGER_MAX_STRING_LEN);
322 properties->version = halProperties->version;
323 convertUuidFromHal(&properties->uuid, &halProperties->uuid);
324 properties->max_sound_models = halProperties->maxSoundModels;
325 properties->max_key_phrases = halProperties->maxKeyPhrases;
326 properties->max_users = halProperties->maxUsers;
327 properties->recognition_modes = halProperties->recognitionModes;
328 properties->capture_transition = (bool)halProperties->captureTransition;
329 properties->max_buffer_ms = halProperties->maxBufferMs;
330 properties->concurrent_capture = (bool)halProperties->concurrentCapture;
331 properties->trigger_in_event = (bool)halProperties->triggerInEvent;
332 properties->power_consumption_mw = halProperties->powerConsumptionMw;
333}
334
335void SoundTriggerHalHidl::convertTriggerPhraseToHal(
336 ISoundTriggerHw::Phrase *halTriggerPhrase,
337 const struct sound_trigger_phrase *triggerPhrase)
338{
339 halTriggerPhrase->id = triggerPhrase->id;
340 halTriggerPhrase->recognitionModes = triggerPhrase->recognition_mode;
341 halTriggerPhrase->users.setToExternal((uint32_t *)&triggerPhrase->users[0], triggerPhrase->num_users);
342 halTriggerPhrase->locale = triggerPhrase->locale;
343 halTriggerPhrase->text = triggerPhrase->text;
344}
345
346ISoundTriggerHw::SoundModel *SoundTriggerHalHidl::convertSoundModelToHal(
347 const struct sound_trigger_sound_model *soundModel)
348{
349 ISoundTriggerHw::SoundModel *halModel = NULL;
350 if (soundModel->type == SOUND_MODEL_TYPE_KEYPHRASE) {
351 ISoundTriggerHw::PhraseSoundModel *halKeyPhraseModel =
352 new ISoundTriggerHw::PhraseSoundModel();
353 struct sound_trigger_phrase_sound_model *keyPhraseModel =
354 (struct sound_trigger_phrase_sound_model *)soundModel;
355 ISoundTriggerHw::Phrase *halPhrases =
356 new ISoundTriggerHw::Phrase[keyPhraseModel->num_phrases];
357
358
359 for (unsigned int i = 0; i < keyPhraseModel->num_phrases; i++) {
360 convertTriggerPhraseToHal(&halPhrases[i],
361 &keyPhraseModel->phrases[i]);
362 }
363 halKeyPhraseModel->phrases.setToExternal(halPhrases, keyPhraseModel->num_phrases);
364 // FIXME: transfer buffer ownership. should have a method for that in hidl_vec
365 halKeyPhraseModel->phrases.resize(keyPhraseModel->num_phrases);
366
367 delete[] halPhrases;
368
369 halModel = (ISoundTriggerHw::SoundModel *)halKeyPhraseModel;
370 } else {
371 halModel = new ISoundTriggerHw::SoundModel();
372 }
373 halModel->type = (SoundModelType)soundModel->type;
374 convertUuidToHal(&halModel->uuid, &soundModel->uuid);
375 convertUuidToHal(&halModel->vendorUuid, &soundModel->vendor_uuid);
376 halModel->data.setToExternal((uint8_t *)soundModel + soundModel->data_offset, soundModel->data_size);
377 halModel->data.resize(soundModel->data_size);
378
379 return halModel;
380}
381
382void SoundTriggerHalHidl::convertPhraseRecognitionExtraToHal(
383 PhraseRecognitionExtra *halExtra,
384 const struct sound_trigger_phrase_recognition_extra *extra)
385{
386 halExtra->id = extra->id;
387 halExtra->recognitionModes = extra->recognition_modes;
388 halExtra->confidenceLevel = extra->confidence_level;
389 ConfidenceLevel *halLevels =
390 new ConfidenceLevel[extra->num_levels];
391 for (unsigned int i = 0; i < extra->num_levels; i++) {
392 halLevels[i].userId = extra->levels[i].user_id;
393 halLevels[i].levelPercent = extra->levels[i].level;
394 }
395 halExtra->levels.setToExternal(halLevels, extra->num_levels);
396 // FIXME: transfer buffer ownership. should have a method for that in hidl_vec
397 halExtra->levels.resize(extra->num_levels);
398
399 delete[] halLevels;
400}
401
402
403ISoundTriggerHw::RecognitionConfig *SoundTriggerHalHidl::convertRecognitionConfigToHal(
404 const struct sound_trigger_recognition_config *config)
405{
406 ISoundTriggerHw::RecognitionConfig *halConfig =
407 new ISoundTriggerHw::RecognitionConfig();
408
409 halConfig->captureHandle = config->capture_handle;
410 halConfig->captureDevice = (AudioDevice)config->capture_device;
411 halConfig->captureRequested = (uint32_t)config->capture_requested;
412
413 PhraseRecognitionExtra *halExtras =
414 new PhraseRecognitionExtra[config->num_phrases];
415
416 for (unsigned int i = 0; i < config->num_phrases; i++) {
417 convertPhraseRecognitionExtraToHal(&halExtras[i],
418 &config->phrases[i]);
419 }
420 halConfig->phrases.setToExternal(halExtras, config->num_phrases);
421 // FIXME: transfer buffer ownership. should have a method for that in hidl_vec
422 halConfig->phrases.resize(config->num_phrases);
423
424 delete[] halExtras;
425
426 halConfig->data.setToExternal((uint8_t *)config + config->data_offset, config->data_size);
427
428 return halConfig;
429}
430
431
432// ISoundTriggerHwCallback
433::android::hardware::Return<void> SoundTriggerHalHidl::recognitionCallback(
434 const ISoundTriggerHwCallback::RecognitionEvent& halEvent,
435 CallbackCookie cookie)
436{
437 sp<SoundModel> model;
438 {
439 AutoMutex lock(mLock);
440 model = mSoundModels.valueFor((SoundModelHandle)cookie);
441 if (model == 0) {
442 return Return<void>();
443 }
444 }
445 struct sound_trigger_recognition_event *event = convertRecognitionEventFromHal(&halEvent);
446 if (event == NULL) {
447 return Return<void>();
448 }
449 event->model = model->mHandle;
450 model->mRecognitionCallback(event, model->mRecognitionCookie);
451
452 free(event);
453
454 return Return<void>();
455}
456
457::android::hardware::Return<void> SoundTriggerHalHidl::phraseRecognitionCallback(
458 const ISoundTriggerHwCallback::PhraseRecognitionEvent& halEvent,
459 CallbackCookie cookie)
460{
461 sp<SoundModel> model;
462 {
463 AutoMutex lock(mLock);
464 model = mSoundModels.valueFor((SoundModelHandle)cookie);
465 if (model == 0) {
466 return Return<void>();
467 }
468 }
469
470 struct sound_trigger_recognition_event *event = convertRecognitionEventFromHal(
471 (const ISoundTriggerHwCallback::RecognitionEvent *)&halEvent);
472 if (event == NULL) {
473 return Return<void>();
474 }
475
476 event->model = model->mHandle;
477 model->mRecognitionCallback(event, model->mRecognitionCookie);
478
479 free(event);
480
481 return Return<void>();
482}
483
484::android::hardware::Return<void> SoundTriggerHalHidl::soundModelCallback(
485 const ISoundTriggerHwCallback::ModelEvent& halEvent,
486 CallbackCookie cookie)
487{
488 sp<SoundModel> model;
489 {
490 AutoMutex lock(mLock);
491 model = mSoundModels.valueFor((SoundModelHandle)cookie);
492 if (model == 0) {
493 return Return<void>();
494 }
495 }
496
497 struct sound_trigger_model_event *event = convertSoundModelEventFromHal(&halEvent);
498 if (event == NULL) {
499 return Return<void>();
500 }
501
502 event->model = model->mHandle;
503 model->mSoundModelCallback(event, model->mSoundModelCookie);
504
505 free(event);
506
507 return Return<void>();
508}
509
510
511struct sound_trigger_model_event *SoundTriggerHalHidl::convertSoundModelEventFromHal(
512 const ISoundTriggerHwCallback::ModelEvent *halEvent)
513{
514 struct sound_trigger_model_event *event = (struct sound_trigger_model_event *)malloc(
515 sizeof(struct sound_trigger_model_event) +
516 halEvent->data.size());
517 if (event == NULL) {
518 return NULL;
519 }
520
521 event->status = (int)halEvent->status;
522 // event->model to be set by caller
523 event->data_offset = sizeof(struct sound_trigger_model_event);
524 event->data_size = halEvent->data.size();
525 uint8_t *dst = (uint8_t *)event + event->data_offset;
526 uint8_t *src = (uint8_t *)&halEvent->data[0];
527 memcpy(dst, src, halEvent->data.size());
528
529 return event;
530}
531
532void SoundTriggerHalHidl::convertPhraseRecognitionExtraFromHal(
533 struct sound_trigger_phrase_recognition_extra *extra,
534 const PhraseRecognitionExtra *halExtra)
535{
536 extra->id = halExtra->id;
537 extra->recognition_modes = halExtra->recognitionModes;
538 extra->confidence_level = halExtra->confidenceLevel;
539
540 size_t i;
541 for (i = 0; i < halExtra->levels.size() && i < SOUND_TRIGGER_MAX_USERS; i++) {
542 extra->levels[i].user_id = halExtra->levels[i].userId;
543 extra->levels[i].level = halExtra->levels[i].levelPercent;
544 }
545 extra->num_levels = (unsigned int)i;
546}
547
548
549struct sound_trigger_recognition_event *SoundTriggerHalHidl::convertRecognitionEventFromHal(
550 const ISoundTriggerHwCallback::RecognitionEvent *halEvent)
551{
552 struct sound_trigger_recognition_event *event;
553
554 if (halEvent->type == SoundModelType::KEYPHRASE) {
555 struct sound_trigger_phrase_recognition_event *phraseEvent =
556 (struct sound_trigger_phrase_recognition_event *)malloc(
557 sizeof(struct sound_trigger_phrase_recognition_event) +
558 halEvent->data.size());
559 if (phraseEvent == NULL) {
560 return NULL;
561 }
562 const ISoundTriggerHwCallback::PhraseRecognitionEvent *halPhraseEvent =
563 (const ISoundTriggerHwCallback::PhraseRecognitionEvent *)halEvent;
564
565 for (unsigned int i = 0; i < halPhraseEvent->phraseExtras.size(); i++) {
566 convertPhraseRecognitionExtraFromHal(&phraseEvent->phrase_extras[i],
567 &halPhraseEvent->phraseExtras[i]);
568 }
569 phraseEvent->num_phrases = halPhraseEvent->phraseExtras.size();
570 event = (struct sound_trigger_recognition_event *)phraseEvent;
571 event->data_offset = sizeof(sound_trigger_phrase_recognition_event);
572 } else {
573 event = (struct sound_trigger_recognition_event *)malloc(
574 sizeof(struct sound_trigger_recognition_event) + halEvent->data.size());
575 if (event == NULL) {
576 return NULL;
577 }
578 event->data_offset = sizeof(sound_trigger_recognition_event);
579 }
580 event->status = (int)halEvent->status;
581 event->type = (sound_trigger_sound_model_type_t)halEvent->type;
582 // event->model to be set by caller
583 event->capture_available = (bool)halEvent->captureAvailable;
584 event->capture_session = halEvent->captureSession;
585 event->capture_delay_ms = halEvent->captureDelayMs;
586 event->capture_preamble_ms = halEvent->capturePreambleMs;
587 event->trigger_in_data = (bool)halEvent->triggerInData;
588 event->audio_config.sample_rate = halEvent->audioConfig.sampleRateHz;
589 event->audio_config.channel_mask = (audio_channel_mask_t)halEvent->audioConfig.channelMask;
590 event->audio_config.format = (audio_format_t)halEvent->audioConfig.format;
591
592 event->data_size = halEvent->data.size();
593 uint8_t *dst = (uint8_t *)event + event->data_offset;
594 uint8_t *src = (uint8_t *)&halEvent->data[0];
595 memcpy(dst, src, halEvent->data.size());
596
597 return event;
598}
599
600} // namespace android