blob: ecbdec4dd40408739b5f7e4ce8b7c9316c189749 [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();
Samuel Saccone34e5d302016-12-09 23:24:29 +000062 if (ret == -EPIPE) {
63 clearService();
64 }
Eric Laurent7a544b42016-08-05 19:01:13 -070065 }
Eric Laurent4b38e7a2016-11-11 13:28:53 -080066 ALOGI("getProperties ret %d", ret);
Eric Laurent7a544b42016-08-05 19:01:13 -070067 return ret;
68}
69
70int SoundTriggerHalHidl::loadSoundModel(struct sound_trigger_sound_model *sound_model,
71 sound_model_callback_t callback,
72 void *cookie,
73 sound_model_handle_t *handle)
74{
75 if (handle == NULL) {
76 return -EINVAL;
77 }
78
79 sp<ISoundTriggerHw> soundtrigger = getService();
80 if (soundtrigger == 0) {
81 return -ENODEV;
82 }
83
84 uint32_t modelId;
85 {
86 AutoMutex lock(mLock);
87 do {
88 modelId = nextUniqueId();
89 ALOGI("loadSoundModel modelId %u", modelId);
90 sp<SoundModel> model = mSoundModels.valueFor(modelId);
91 ALOGI("loadSoundModel model %p", model.get());
92 } while (mSoundModels.valueFor(modelId) != 0 && modelId != 0);
93 }
94 LOG_ALWAYS_FATAL_IF(modelId == 0,
95 "loadSoundModel(): wrap around in sound model IDs, num loaded models %zd",
96 mSoundModels.size());
97
98 ISoundTriggerHw::SoundModel *halSoundModel =
99 convertSoundModelToHal(sound_model);
100 if (halSoundModel == NULL) {
101 return -EINVAL;
102 }
103
104 Return<void> hidlReturn;
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800105 int ret;
Eric Laurent7a544b42016-08-05 19:01:13 -0700106 SoundModelHandle halHandle;
107 {
108 AutoMutex lock(mHalLock);
109 if (sound_model->type == SOUND_MODEL_TYPE_KEYPHRASE) {
110 hidlReturn = soundtrigger->loadPhraseSoundModel(
111 *(const ISoundTriggerHw::PhraseSoundModel *)halSoundModel,
112 this, modelId, [&](int32_t retval, auto res) {
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800113 ret = retval;
Eric Laurent7a544b42016-08-05 19:01:13 -0700114 halHandle = res;
115 });
116
117 } else {
118 hidlReturn = soundtrigger->loadSoundModel(*halSoundModel,
119 this, modelId, [&](int32_t retval, auto res) {
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800120 ret = retval;
Eric Laurent7a544b42016-08-05 19:01:13 -0700121 halHandle = res;
122 });
123 }
124 }
125
126 delete halSoundModel;
127
Eric Laurent7a544b42016-08-05 19:01:13 -0700128 if (hidlReturn.getStatus().isOk()) {
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800129 if (ret == 0) {
130 AutoMutex lock(mLock);
131 *handle = (sound_model_handle_t)modelId;
132 sp<SoundModel> model = new SoundModel(*handle, callback, cookie, halHandle);
133 mSoundModels.add(*handle, model);
134 }
Eric Laurent7a544b42016-08-05 19:01:13 -0700135 } else {
136 ret = (int)hidlReturn.getStatus().transactionError();
137 ALOGE("loadSoundModel error %d", ret);
Samuel Saccone34e5d302016-12-09 23:24:29 +0000138 if (ret == -EPIPE) {
139 clearService();
140 }
Eric Laurent7a544b42016-08-05 19:01:13 -0700141 }
142
143
144 return ret;
145}
146
147int SoundTriggerHalHidl::unloadSoundModel(sound_model_handle_t handle)
148{
149 sp<ISoundTriggerHw> soundtrigger = getService();
150 if (soundtrigger == 0) {
151 return -ENODEV;
152 }
153
154 sp<SoundModel> model = removeModel(handle);
155 if (model == 0) {
156 ALOGE("unloadSoundModel model not found for handle %u", handle);
157 return -EINVAL;
158 }
159
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800160 Return<int32_t> hidlReturn(0);
Eric Laurent7a544b42016-08-05 19:01:13 -0700161 {
162 AutoMutex lock(mHalLock);
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800163 hidlReturn = soundtrigger->unloadSoundModel(model->mHalHandle);
Eric Laurent7a544b42016-08-05 19:01:13 -0700164 }
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800165 int ret = (int)hidlReturn.getStatus().transactionError();
Eric Laurent7a544b42016-08-05 19:01:13 -0700166 ALOGE_IF(ret != 0, "unloadSoundModel error %d", ret);
Samuel Saccone34e5d302016-12-09 23:24:29 +0000167 if (ret == -EPIPE) {
168 clearService();
169 }
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800170 if (ret == 0) {
171 ret = hidlReturn;
172 }
Eric Laurent7a544b42016-08-05 19:01:13 -0700173 return ret;
174}
175
176int SoundTriggerHalHidl::startRecognition(sound_model_handle_t handle,
177 const struct sound_trigger_recognition_config *config,
178 recognition_callback_t callback,
179 void *cookie)
180{
181 sp<ISoundTriggerHw> soundtrigger = getService();
182 if (soundtrigger == 0) {
183 return -ENODEV;
184 }
185
186 sp<SoundModel> model = getModel(handle);
187 if (model == 0) {
188 ALOGE("startRecognition model not found for handle %u", handle);
189 return -EINVAL;
190 }
191
192 model->mRecognitionCallback = callback;
193 model->mRecognitionCookie = cookie;
194
195 ISoundTriggerHw::RecognitionConfig *halConfig =
196 convertRecognitionConfigToHal(config);
197
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800198 Return<int32_t> hidlReturn(0);
Eric Laurent7a544b42016-08-05 19:01:13 -0700199 {
200 AutoMutex lock(mHalLock);
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800201 hidlReturn = soundtrigger->startRecognition(model->mHalHandle, *halConfig, this, handle);
Eric Laurent7a544b42016-08-05 19:01:13 -0700202 }
203
204 delete halConfig;
205
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800206 int ret = (int)hidlReturn.getStatus().transactionError();
Eric Laurent7a544b42016-08-05 19:01:13 -0700207 ALOGE_IF(ret != 0, "startRecognition error %d", ret);
Samuel Saccone34e5d302016-12-09 23:24:29 +0000208 if (ret == -EPIPE) {
209 clearService();
210 }
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800211 if (ret == 0) {
212 ret = hidlReturn;
213 }
Eric Laurent7a544b42016-08-05 19:01:13 -0700214 return ret;
215}
216
217int SoundTriggerHalHidl::stopRecognition(sound_model_handle_t handle)
218{
219 sp<ISoundTriggerHw> soundtrigger = getService();
220 if (soundtrigger == 0) {
221 return -ENODEV;
222 }
223
224 sp<SoundModel> model = getModel(handle);
225 if (model == 0) {
226 ALOGE("stopRecognition model not found for handle %u", handle);
227 return -EINVAL;
228 }
229
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800230 Return<int32_t> hidlReturn(0);
Eric Laurent7a544b42016-08-05 19:01:13 -0700231 {
232 AutoMutex lock(mHalLock);
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800233 hidlReturn = soundtrigger->stopRecognition(model->mHalHandle);
Eric Laurent7a544b42016-08-05 19:01:13 -0700234 }
235
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800236 int ret = (int)hidlReturn.getStatus().transactionError();
Eric Laurent7a544b42016-08-05 19:01:13 -0700237 ALOGE_IF(ret != 0, "stopRecognition error %d", ret);
Samuel Saccone34e5d302016-12-09 23:24:29 +0000238 if (ret == -EPIPE) {
239 clearService();
240 }
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800241 if (ret == 0) {
242 ret = hidlReturn;
243 }
Eric Laurent7a544b42016-08-05 19:01:13 -0700244 return ret;
245}
246
247int SoundTriggerHalHidl::stopAllRecognitions()
248{
249 sp<ISoundTriggerHw> soundtrigger = getService();
250 if (soundtrigger == 0) {
251 return -ENODEV;
252 }
253
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800254 Return<int32_t> hidlReturn(0);
Eric Laurent7a544b42016-08-05 19:01:13 -0700255 {
256 AutoMutex lock(mHalLock);
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800257 hidlReturn = soundtrigger->stopAllRecognitions();
Eric Laurent7a544b42016-08-05 19:01:13 -0700258 }
259
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800260 int ret = (int)hidlReturn.getStatus().transactionError();
Eric Laurent7a544b42016-08-05 19:01:13 -0700261 ALOGE_IF(ret != 0, "stopAllRecognitions error %d", ret);
Samuel Saccone34e5d302016-12-09 23:24:29 +0000262 if (ret == -EPIPE) {
263 clearService();
264 }
Eric Laurent4b38e7a2016-11-11 13:28:53 -0800265 if (ret == 0) {
266 ret = hidlReturn;
267 }
Eric Laurent7a544b42016-08-05 19:01:13 -0700268 return ret;
269}
270
271SoundTriggerHalHidl::SoundTriggerHalHidl(const char *moduleName)
272 : mModuleName(moduleName), mNextUniqueId(1)
273{
274}
275
Eric Laurent7a544b42016-08-05 19:01:13 -0700276SoundTriggerHalHidl::~SoundTriggerHalHidl()
277{
278}
279
280sp<ISoundTriggerHw> SoundTriggerHalHidl::getService()
281{
282 AutoMutex lock(mLock);
283 if (mISoundTrigger == 0) {
284 if (mModuleName == NULL) {
285 mModuleName = "primary";
286 }
287 std::string serviceName = "sound_trigger.";
288 serviceName.append(mModuleName);
289 mISoundTrigger = ISoundTriggerHw::getService(serviceName);
290 }
291 return mISoundTrigger;
292}
293
Samuel Saccone34e5d302016-12-09 23:24:29 +0000294void SoundTriggerHalHidl::clearService()
Eric Laurent7a544b42016-08-05 19:01:13 -0700295{
Samuel Saccone34e5d302016-12-09 23:24:29 +0000296 AutoMutex lock(mLock);
297 mISoundTrigger = 0;
Eric Laurent7a544b42016-08-05 19:01:13 -0700298}
299
300sp<SoundTriggerHalHidl::SoundModel> SoundTriggerHalHidl::getModel(sound_model_handle_t handle)
301{
302 AutoMutex lock(mLock);
303 return mSoundModels.valueFor(handle);
304}
305
306sp<SoundTriggerHalHidl::SoundModel> SoundTriggerHalHidl::removeModel(sound_model_handle_t handle)
307{
308 AutoMutex lock(mLock);
309 sp<SoundModel> model = mSoundModels.valueFor(handle);
310 mSoundModels.removeItem(handle);
311 return model;
312}
313
314uint32_t SoundTriggerHalHidl::nextUniqueId()
315{
316 return (uint32_t) atomic_fetch_add_explicit(&mNextUniqueId,
317 (uint_fast32_t) 1, memory_order_acq_rel);
318}
319
320void SoundTriggerHalHidl::convertUuidToHal(Uuid *halUuid,
Eric Laurentf7854d42016-10-14 15:57:18 -0700321 const sound_trigger_uuid_t *uuid)
Eric Laurent7a544b42016-08-05 19:01:13 -0700322{
323 halUuid->timeLow = uuid->timeLow;
324 halUuid->timeMid = uuid->timeMid;
325 halUuid->versionAndTimeHigh = uuid->timeHiAndVersion;
326 halUuid->variantAndClockSeqHigh = uuid->clockSeq;
327 memcpy(halUuid->node.data(), &uuid->node[0], sizeof(uuid->node));
328}
329
Eric Laurentf7854d42016-10-14 15:57:18 -0700330void SoundTriggerHalHidl::convertUuidFromHal(sound_trigger_uuid_t *uuid,
Eric Laurent7a544b42016-08-05 19:01:13 -0700331 const Uuid *halUuid)
332{
333 uuid->timeLow = halUuid->timeLow;
334 uuid->timeMid = halUuid->timeMid;
335 uuid->timeHiAndVersion = halUuid->versionAndTimeHigh;
336 uuid->clockSeq = halUuid->variantAndClockSeqHigh;
337 memcpy(&uuid->node[0], halUuid->node.data(), sizeof(uuid->node));
338}
339
340void SoundTriggerHalHidl::convertPropertiesFromHal(
341 struct sound_trigger_properties *properties,
342 const ISoundTriggerHw::Properties *halProperties)
343{
344 strlcpy(properties->implementor,
345 halProperties->implementor.c_str(), SOUND_TRIGGER_MAX_STRING_LEN);
346 strlcpy(properties->description,
347 halProperties->description.c_str(), SOUND_TRIGGER_MAX_STRING_LEN);
348 properties->version = halProperties->version;
349 convertUuidFromHal(&properties->uuid, &halProperties->uuid);
350 properties->max_sound_models = halProperties->maxSoundModels;
351 properties->max_key_phrases = halProperties->maxKeyPhrases;
352 properties->max_users = halProperties->maxUsers;
353 properties->recognition_modes = halProperties->recognitionModes;
354 properties->capture_transition = (bool)halProperties->captureTransition;
355 properties->max_buffer_ms = halProperties->maxBufferMs;
356 properties->concurrent_capture = (bool)halProperties->concurrentCapture;
357 properties->trigger_in_event = (bool)halProperties->triggerInEvent;
358 properties->power_consumption_mw = halProperties->powerConsumptionMw;
359}
360
361void SoundTriggerHalHidl::convertTriggerPhraseToHal(
362 ISoundTriggerHw::Phrase *halTriggerPhrase,
363 const struct sound_trigger_phrase *triggerPhrase)
364{
365 halTriggerPhrase->id = triggerPhrase->id;
366 halTriggerPhrase->recognitionModes = triggerPhrase->recognition_mode;
367 halTriggerPhrase->users.setToExternal((uint32_t *)&triggerPhrase->users[0], triggerPhrase->num_users);
368 halTriggerPhrase->locale = triggerPhrase->locale;
369 halTriggerPhrase->text = triggerPhrase->text;
370}
371
372ISoundTriggerHw::SoundModel *SoundTriggerHalHidl::convertSoundModelToHal(
373 const struct sound_trigger_sound_model *soundModel)
374{
375 ISoundTriggerHw::SoundModel *halModel = NULL;
376 if (soundModel->type == SOUND_MODEL_TYPE_KEYPHRASE) {
377 ISoundTriggerHw::PhraseSoundModel *halKeyPhraseModel =
378 new ISoundTriggerHw::PhraseSoundModel();
379 struct sound_trigger_phrase_sound_model *keyPhraseModel =
380 (struct sound_trigger_phrase_sound_model *)soundModel;
381 ISoundTriggerHw::Phrase *halPhrases =
382 new ISoundTriggerHw::Phrase[keyPhraseModel->num_phrases];
383
384
385 for (unsigned int i = 0; i < keyPhraseModel->num_phrases; i++) {
386 convertTriggerPhraseToHal(&halPhrases[i],
387 &keyPhraseModel->phrases[i]);
388 }
389 halKeyPhraseModel->phrases.setToExternal(halPhrases, keyPhraseModel->num_phrases);
390 // FIXME: transfer buffer ownership. should have a method for that in hidl_vec
391 halKeyPhraseModel->phrases.resize(keyPhraseModel->num_phrases);
392
393 delete[] halPhrases;
394
395 halModel = (ISoundTriggerHw::SoundModel *)halKeyPhraseModel;
396 } else {
397 halModel = new ISoundTriggerHw::SoundModel();
398 }
399 halModel->type = (SoundModelType)soundModel->type;
400 convertUuidToHal(&halModel->uuid, &soundModel->uuid);
401 convertUuidToHal(&halModel->vendorUuid, &soundModel->vendor_uuid);
402 halModel->data.setToExternal((uint8_t *)soundModel + soundModel->data_offset, soundModel->data_size);
403 halModel->data.resize(soundModel->data_size);
404
405 return halModel;
406}
407
408void SoundTriggerHalHidl::convertPhraseRecognitionExtraToHal(
409 PhraseRecognitionExtra *halExtra,
410 const struct sound_trigger_phrase_recognition_extra *extra)
411{
412 halExtra->id = extra->id;
413 halExtra->recognitionModes = extra->recognition_modes;
414 halExtra->confidenceLevel = extra->confidence_level;
415 ConfidenceLevel *halLevels =
416 new ConfidenceLevel[extra->num_levels];
417 for (unsigned int i = 0; i < extra->num_levels; i++) {
418 halLevels[i].userId = extra->levels[i].user_id;
419 halLevels[i].levelPercent = extra->levels[i].level;
420 }
421 halExtra->levels.setToExternal(halLevels, extra->num_levels);
422 // FIXME: transfer buffer ownership. should have a method for that in hidl_vec
423 halExtra->levels.resize(extra->num_levels);
424
425 delete[] halLevels;
426}
427
428
429ISoundTriggerHw::RecognitionConfig *SoundTriggerHalHidl::convertRecognitionConfigToHal(
430 const struct sound_trigger_recognition_config *config)
431{
432 ISoundTriggerHw::RecognitionConfig *halConfig =
433 new ISoundTriggerHw::RecognitionConfig();
434
435 halConfig->captureHandle = config->capture_handle;
436 halConfig->captureDevice = (AudioDevice)config->capture_device;
437 halConfig->captureRequested = (uint32_t)config->capture_requested;
438
439 PhraseRecognitionExtra *halExtras =
440 new PhraseRecognitionExtra[config->num_phrases];
441
442 for (unsigned int i = 0; i < config->num_phrases; i++) {
443 convertPhraseRecognitionExtraToHal(&halExtras[i],
444 &config->phrases[i]);
445 }
446 halConfig->phrases.setToExternal(halExtras, config->num_phrases);
447 // FIXME: transfer buffer ownership. should have a method for that in hidl_vec
448 halConfig->phrases.resize(config->num_phrases);
449
450 delete[] halExtras;
451
452 halConfig->data.setToExternal((uint8_t *)config + config->data_offset, config->data_size);
453
454 return halConfig;
455}
456
457
458// ISoundTriggerHwCallback
459::android::hardware::Return<void> SoundTriggerHalHidl::recognitionCallback(
460 const ISoundTriggerHwCallback::RecognitionEvent& halEvent,
461 CallbackCookie cookie)
462{
463 sp<SoundModel> model;
464 {
465 AutoMutex lock(mLock);
466 model = mSoundModels.valueFor((SoundModelHandle)cookie);
467 if (model == 0) {
468 return Return<void>();
469 }
470 }
471 struct sound_trigger_recognition_event *event = convertRecognitionEventFromHal(&halEvent);
472 if (event == NULL) {
473 return Return<void>();
474 }
475 event->model = model->mHandle;
476 model->mRecognitionCallback(event, model->mRecognitionCookie);
477
478 free(event);
479
480 return Return<void>();
481}
482
483::android::hardware::Return<void> SoundTriggerHalHidl::phraseRecognitionCallback(
484 const ISoundTriggerHwCallback::PhraseRecognitionEvent& halEvent,
485 CallbackCookie cookie)
486{
487 sp<SoundModel> model;
488 {
489 AutoMutex lock(mLock);
490 model = mSoundModels.valueFor((SoundModelHandle)cookie);
491 if (model == 0) {
492 return Return<void>();
493 }
494 }
495
496 struct sound_trigger_recognition_event *event = convertRecognitionEventFromHal(
497 (const ISoundTriggerHwCallback::RecognitionEvent *)&halEvent);
498 if (event == NULL) {
499 return Return<void>();
500 }
501
502 event->model = model->mHandle;
503 model->mRecognitionCallback(event, model->mRecognitionCookie);
504
505 free(event);
506
507 return Return<void>();
508}
509
510::android::hardware::Return<void> SoundTriggerHalHidl::soundModelCallback(
511 const ISoundTriggerHwCallback::ModelEvent& halEvent,
512 CallbackCookie cookie)
513{
514 sp<SoundModel> model;
515 {
516 AutoMutex lock(mLock);
517 model = mSoundModels.valueFor((SoundModelHandle)cookie);
518 if (model == 0) {
519 return Return<void>();
520 }
521 }
522
523 struct sound_trigger_model_event *event = convertSoundModelEventFromHal(&halEvent);
524 if (event == NULL) {
525 return Return<void>();
526 }
527
528 event->model = model->mHandle;
529 model->mSoundModelCallback(event, model->mSoundModelCookie);
530
531 free(event);
532
533 return Return<void>();
534}
535
536
537struct sound_trigger_model_event *SoundTriggerHalHidl::convertSoundModelEventFromHal(
538 const ISoundTriggerHwCallback::ModelEvent *halEvent)
539{
540 struct sound_trigger_model_event *event = (struct sound_trigger_model_event *)malloc(
541 sizeof(struct sound_trigger_model_event) +
542 halEvent->data.size());
543 if (event == NULL) {
544 return NULL;
545 }
546
547 event->status = (int)halEvent->status;
548 // event->model to be set by caller
549 event->data_offset = sizeof(struct sound_trigger_model_event);
550 event->data_size = halEvent->data.size();
551 uint8_t *dst = (uint8_t *)event + event->data_offset;
552 uint8_t *src = (uint8_t *)&halEvent->data[0];
553 memcpy(dst, src, halEvent->data.size());
554
555 return event;
556}
557
558void SoundTriggerHalHidl::convertPhraseRecognitionExtraFromHal(
559 struct sound_trigger_phrase_recognition_extra *extra,
560 const PhraseRecognitionExtra *halExtra)
561{
562 extra->id = halExtra->id;
563 extra->recognition_modes = halExtra->recognitionModes;
564 extra->confidence_level = halExtra->confidenceLevel;
565
566 size_t i;
567 for (i = 0; i < halExtra->levels.size() && i < SOUND_TRIGGER_MAX_USERS; i++) {
568 extra->levels[i].user_id = halExtra->levels[i].userId;
569 extra->levels[i].level = halExtra->levels[i].levelPercent;
570 }
571 extra->num_levels = (unsigned int)i;
572}
573
574
575struct sound_trigger_recognition_event *SoundTriggerHalHidl::convertRecognitionEventFromHal(
576 const ISoundTriggerHwCallback::RecognitionEvent *halEvent)
577{
578 struct sound_trigger_recognition_event *event;
579
580 if (halEvent->type == SoundModelType::KEYPHRASE) {
581 struct sound_trigger_phrase_recognition_event *phraseEvent =
582 (struct sound_trigger_phrase_recognition_event *)malloc(
583 sizeof(struct sound_trigger_phrase_recognition_event) +
584 halEvent->data.size());
585 if (phraseEvent == NULL) {
586 return NULL;
587 }
588 const ISoundTriggerHwCallback::PhraseRecognitionEvent *halPhraseEvent =
589 (const ISoundTriggerHwCallback::PhraseRecognitionEvent *)halEvent;
590
591 for (unsigned int i = 0; i < halPhraseEvent->phraseExtras.size(); i++) {
592 convertPhraseRecognitionExtraFromHal(&phraseEvent->phrase_extras[i],
593 &halPhraseEvent->phraseExtras[i]);
594 }
595 phraseEvent->num_phrases = halPhraseEvent->phraseExtras.size();
596 event = (struct sound_trigger_recognition_event *)phraseEvent;
597 event->data_offset = sizeof(sound_trigger_phrase_recognition_event);
598 } else {
599 event = (struct sound_trigger_recognition_event *)malloc(
600 sizeof(struct sound_trigger_recognition_event) + halEvent->data.size());
601 if (event == NULL) {
602 return NULL;
603 }
604 event->data_offset = sizeof(sound_trigger_recognition_event);
605 }
606 event->status = (int)halEvent->status;
607 event->type = (sound_trigger_sound_model_type_t)halEvent->type;
608 // event->model to be set by caller
609 event->capture_available = (bool)halEvent->captureAvailable;
610 event->capture_session = halEvent->captureSession;
611 event->capture_delay_ms = halEvent->captureDelayMs;
612 event->capture_preamble_ms = halEvent->capturePreambleMs;
613 event->trigger_in_data = (bool)halEvent->triggerInData;
614 event->audio_config.sample_rate = halEvent->audioConfig.sampleRateHz;
615 event->audio_config.channel_mask = (audio_channel_mask_t)halEvent->audioConfig.channelMask;
616 event->audio_config.format = (audio_format_t)halEvent->audioConfig.format;
617
618 event->data_size = halEvent->data.size();
619 uint8_t *dst = (uint8_t *)event + event->data_offset;
620 uint8_t *src = (uint8_t *)&halEvent->data[0];
621 memcpy(dst, src, halEvent->data.size());
622
623 return event;
624}
625
626} // namespace android