blob: 612772cc63c335bd0f851b4e2192942628dff557 [file] [log] [blame]
Eric Laurent27ef4d82016-10-14 15:46:06 -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 "SoundTriggerHalImpl"
18//#define LOG_NDEBUG 0
19
Eric Laurent27ef4d82016-10-14 15:46:06 -070020#include "SoundTriggerHalImpl.h"
Mikhail Naganov0bbc4aa2017-12-22 13:23:08 -080021#include <android/log.h>
Eric Laurent27ef4d82016-10-14 15:46:06 -070022
23namespace android {
24namespace hardware {
25namespace soundtrigger {
26namespace V2_0 {
27namespace implementation {
28
29// static
Mikhail Naganov0bbc4aa2017-12-22 13:23:08 -080030void SoundTriggerHalImpl::soundModelCallback(struct sound_trigger_model_event* halEvent,
31 void* cookie) {
Eric Laurent27ef4d82016-10-14 15:46:06 -070032 if (halEvent == NULL) {
33 ALOGW("soundModelCallback called with NULL event");
34 return;
35 }
36 sp<SoundModelClient> client =
Mikhail Naganov0bbc4aa2017-12-22 13:23:08 -080037 wp<SoundModelClient>(static_cast<SoundModelClient*>(cookie)).promote();
Eric Laurent27ef4d82016-10-14 15:46:06 -070038 if (client == 0) {
39 ALOGW("soundModelCallback called on stale client");
40 return;
41 }
Mikhail Naganovdfdc3bb2017-12-22 13:35:23 -080042 if (halEvent->model != client->getHalHandle()) {
Eric Laurent27ef4d82016-10-14 15:46:06 -070043 ALOGW("soundModelCallback call with wrong handle %d on client with handle %d",
Mikhail Naganovdfdc3bb2017-12-22 13:35:23 -080044 (int)halEvent->model, (int)client->getHalHandle());
Eric Laurent27ef4d82016-10-14 15:46:06 -070045 return;
46 }
47
Mikhail Naganovdfdc3bb2017-12-22 13:35:23 -080048 client->soundModelCallback(halEvent);
Eric Laurent27ef4d82016-10-14 15:46:06 -070049}
50
51// static
Mikhail Naganov0bbc4aa2017-12-22 13:23:08 -080052void SoundTriggerHalImpl::recognitionCallback(struct sound_trigger_recognition_event* halEvent,
53 void* cookie) {
Eric Laurent27ef4d82016-10-14 15:46:06 -070054 if (halEvent == NULL) {
55 ALOGW("recognitionCallback call NULL event");
56 return;
57 }
58 sp<SoundModelClient> client =
Mikhail Naganov0bbc4aa2017-12-22 13:23:08 -080059 wp<SoundModelClient>(static_cast<SoundModelClient*>(cookie)).promote();
Eric Laurent27ef4d82016-10-14 15:46:06 -070060 if (client == 0) {
61 ALOGW("soundModelCallback called on stale client");
62 return;
63 }
64
Mikhail Naganovdfdc3bb2017-12-22 13:35:23 -080065 client->recognitionCallback(halEvent);
Eric Laurent27ef4d82016-10-14 15:46:06 -070066}
67
Mikhail Naganovdfdc3bb2017-12-22 13:35:23 -080068Return<void> SoundTriggerHalImpl::getProperties(ISoundTriggerHw::getProperties_cb _hidl_cb) {
Eric Laurent27ef4d82016-10-14 15:46:06 -070069 ALOGV("getProperties() mHwDevice %p", mHwDevice);
70 int ret;
71 struct sound_trigger_properties halProperties;
72 ISoundTriggerHw::Properties properties;
73
74 if (mHwDevice == NULL) {
75 ret = -ENODEV;
76 goto exit;
77 }
78
79 ret = mHwDevice->get_properties(mHwDevice, &halProperties);
80
81 convertPropertiesFromHal(&properties, &halProperties);
82
Mikhail Naganov0bbc4aa2017-12-22 13:23:08 -080083 ALOGV("getProperties implementor %s recognitionModes %08x", properties.implementor.c_str(),
84 properties.recognitionModes);
Eric Laurent27ef4d82016-10-14 15:46:06 -070085
86exit:
87 _hidl_cb(ret, properties);
88 return Void();
89}
90
91int SoundTriggerHalImpl::doLoadSoundModel(const ISoundTriggerHw::SoundModel& soundModel,
Mikhail Naganovdfdc3bb2017-12-22 13:35:23 -080092 sp<SoundModelClient> client) {
Eric Laurent27ef4d82016-10-14 15:46:06 -070093 int32_t ret = 0;
Mikhail Naganov0bbc4aa2017-12-22 13:23:08 -080094 struct sound_trigger_sound_model* halSoundModel;
Eric Laurent27ef4d82016-10-14 15:46:06 -070095
96 ALOGV("doLoadSoundModel() data size %zu", soundModel.data.size());
97
98 if (mHwDevice == NULL) {
99 ret = -ENODEV;
100 goto exit;
101 }
102
103 halSoundModel = convertSoundModelToHal(&soundModel);
104 if (halSoundModel == NULL) {
105 ret = -EINVAL;
106 goto exit;
107 }
108
Mikhail Naganovdfdc3bb2017-12-22 13:35:23 -0800109 sound_model_handle_t halHandle;
Mikhail Naganov0bbc4aa2017-12-22 13:23:08 -0800110 ret = mHwDevice->load_sound_model(mHwDevice, halSoundModel, soundModelCallback, client.get(),
Mikhail Naganovdfdc3bb2017-12-22 13:35:23 -0800111 &halHandle);
Eric Laurent27ef4d82016-10-14 15:46:06 -0700112
113 free(halSoundModel);
114
115 if (ret != 0) {
116 goto exit;
117 }
118
Mikhail Naganovdfdc3bb2017-12-22 13:35:23 -0800119 client->setHalHandle(halHandle);
Eric Laurent27ef4d82016-10-14 15:46:06 -0700120 {
121 AutoMutex lock(mLock);
Mikhail Naganovdfdc3bb2017-12-22 13:35:23 -0800122 mClients.add(client->getId(), client);
Eric Laurent27ef4d82016-10-14 15:46:06 -0700123 }
124
125exit:
126 return ret;
127}
128
129Return<void> SoundTriggerHalImpl::loadSoundModel(const ISoundTriggerHw::SoundModel& soundModel,
130 const sp<ISoundTriggerHwCallback>& callback,
131 ISoundTriggerHwCallback::CallbackCookie cookie,
Mikhail Naganovdfdc3bb2017-12-22 13:35:23 -0800132 ISoundTriggerHw::loadSoundModel_cb _hidl_cb) {
133 sp<SoundModelClient> client = new SoundModelClient_2_0(nextUniqueModelId(), cookie, callback);
134 _hidl_cb(doLoadSoundModel(soundModel, client), client->getId());
Eric Laurent27ef4d82016-10-14 15:46:06 -0700135 return Void();
136}
137
138Return<void> SoundTriggerHalImpl::loadPhraseSoundModel(
Mikhail Naganov0bbc4aa2017-12-22 13:23:08 -0800139 const ISoundTriggerHw::PhraseSoundModel& soundModel,
140 const sp<ISoundTriggerHwCallback>& callback, ISoundTriggerHwCallback::CallbackCookie cookie,
141 ISoundTriggerHw::loadPhraseSoundModel_cb _hidl_cb) {
Mikhail Naganovdfdc3bb2017-12-22 13:35:23 -0800142 sp<SoundModelClient> client = new SoundModelClient_2_0(nextUniqueModelId(), cookie, callback);
143 _hidl_cb(doLoadSoundModel((const ISoundTriggerHw::SoundModel&)soundModel, client),
144 client->getId());
Eric Laurent27ef4d82016-10-14 15:46:06 -0700145 return Void();
146}
147
Mikhail Naganov0bbc4aa2017-12-22 13:23:08 -0800148Return<int32_t> SoundTriggerHalImpl::unloadSoundModel(SoundModelHandle modelHandle) {
Eric Laurent27ef4d82016-10-14 15:46:06 -0700149 int32_t ret;
150 sp<SoundModelClient> client;
151
152 if (mHwDevice == NULL) {
153 ret = -ENODEV;
154 goto exit;
155 }
156
157 {
158 AutoMutex lock(mLock);
159 client = mClients.valueFor(modelHandle);
160 if (client == 0) {
161 ret = -ENOSYS;
162 goto exit;
163 }
164 }
165
Mikhail Naganovdfdc3bb2017-12-22 13:35:23 -0800166 ret = mHwDevice->unload_sound_model(mHwDevice, client->getHalHandle());
Eric Laurent27ef4d82016-10-14 15:46:06 -0700167
168 mClients.removeItem(modelHandle);
169
170exit:
171 return ret;
172}
173
Mikhail Naganov0bbc4aa2017-12-22 13:23:08 -0800174Return<int32_t> SoundTriggerHalImpl::startRecognition(
Mikhail Naganovdfdc3bb2017-12-22 13:35:23 -0800175 SoundModelHandle modelHandle, const ISoundTriggerHw::RecognitionConfig& config) {
Eric Laurent27ef4d82016-10-14 15:46:06 -0700176 int32_t ret;
177 sp<SoundModelClient> client;
Mikhail Naganov0bbc4aa2017-12-22 13:23:08 -0800178 struct sound_trigger_recognition_config* halConfig;
Eric Laurent27ef4d82016-10-14 15:46:06 -0700179
180 if (mHwDevice == NULL) {
181 ret = -ENODEV;
182 goto exit;
183 }
184
185 {
186 AutoMutex lock(mLock);
187 client = mClients.valueFor(modelHandle);
188 if (client == 0) {
189 ret = -ENOSYS;
190 goto exit;
191 }
192 }
193
Eric Laurent27ef4d82016-10-14 15:46:06 -0700194 halConfig = convertRecognitionConfigToHal(&config);
195
196 if (halConfig == NULL) {
197 ret = -EINVAL;
198 goto exit;
199 }
Mikhail Naganovdfdc3bb2017-12-22 13:35:23 -0800200 ret = mHwDevice->start_recognition(mHwDevice, client->getHalHandle(), halConfig,
Mikhail Naganov0bbc4aa2017-12-22 13:23:08 -0800201 recognitionCallback, client.get());
Eric Laurent27ef4d82016-10-14 15:46:06 -0700202
203 free(halConfig);
204
205exit:
206 return ret;
207}
208
Mikhail Naganov0bbc4aa2017-12-22 13:23:08 -0800209Return<int32_t> SoundTriggerHalImpl::stopRecognition(SoundModelHandle modelHandle) {
Eric Laurent27ef4d82016-10-14 15:46:06 -0700210 int32_t ret;
211 sp<SoundModelClient> client;
212 if (mHwDevice == NULL) {
213 ret = -ENODEV;
214 goto exit;
215 }
216
217 {
218 AutoMutex lock(mLock);
219 client = mClients.valueFor(modelHandle);
220 if (client == 0) {
221 ret = -ENOSYS;
222 goto exit;
223 }
224 }
225
Mikhail Naganovdfdc3bb2017-12-22 13:35:23 -0800226 ret = mHwDevice->stop_recognition(mHwDevice, client->getHalHandle());
Eric Laurent27ef4d82016-10-14 15:46:06 -0700227
228exit:
229 return ret;
230}
231
Mikhail Naganov0bbc4aa2017-12-22 13:23:08 -0800232Return<int32_t> SoundTriggerHalImpl::stopAllRecognitions() {
Eric Laurent27ef4d82016-10-14 15:46:06 -0700233 int32_t ret;
234 if (mHwDevice == NULL) {
235 ret = -ENODEV;
236 goto exit;
237 }
238
239 if (mHwDevice->common.version >= SOUND_TRIGGER_DEVICE_API_VERSION_1_1 &&
Mikhail Naganov0bbc4aa2017-12-22 13:23:08 -0800240 mHwDevice->stop_all_recognitions) {
Eric Laurent27ef4d82016-10-14 15:46:06 -0700241 ret = mHwDevice->stop_all_recognitions(mHwDevice);
242 } else {
243 ret = -ENOSYS;
244 }
245exit:
246 return ret;
247}
248
Mikhail Naganov3acaa662017-04-13 11:00:11 -0700249SoundTriggerHalImpl::SoundTriggerHalImpl()
Michael Dooleyecac1122018-09-28 07:25:12 +0000250 : mModuleName("primary"), mHwDevice(NULL), mNextModelId(1) {}
Eric Laurent27ef4d82016-10-14 15:46:06 -0700251
Mikhail Naganov0bbc4aa2017-12-22 13:23:08 -0800252void SoundTriggerHalImpl::onFirstRef() {
253 const hw_module_t* mod;
Eric Laurent27ef4d82016-10-14 15:46:06 -0700254 int rc;
255
Eric Laurent27ef4d82016-10-14 15:46:06 -0700256 rc = hw_get_module_by_class(SOUND_TRIGGER_HARDWARE_MODULE_ID, mModuleName, &mod);
257 if (rc != 0) {
Mikhail Naganov0bbc4aa2017-12-22 13:23:08 -0800258 ALOGE("couldn't load sound trigger module %s.%s (%s)", SOUND_TRIGGER_HARDWARE_MODULE_ID,
259 mModuleName, strerror(-rc));
Eric Laurent27ef4d82016-10-14 15:46:06 -0700260 return;
261 }
262 rc = sound_trigger_hw_device_open(mod, &mHwDevice);
263 if (rc != 0) {
264 ALOGE("couldn't open sound trigger hw device in %s.%s (%s)",
265 SOUND_TRIGGER_HARDWARE_MODULE_ID, mModuleName, strerror(-rc));
266 mHwDevice = NULL;
267 return;
268 }
269 if (mHwDevice->common.version < SOUND_TRIGGER_DEVICE_API_VERSION_1_0 ||
Mikhail Naganov0bbc4aa2017-12-22 13:23:08 -0800270 mHwDevice->common.version > SOUND_TRIGGER_DEVICE_API_VERSION_CURRENT) {
Eric Laurent27ef4d82016-10-14 15:46:06 -0700271 ALOGE("wrong sound trigger hw device version %04x", mHwDevice->common.version);
272 sound_trigger_hw_device_close(mHwDevice);
273 mHwDevice = NULL;
274 return;
275 }
276
277 ALOGI("onFirstRef() mModuleName %s mHwDevice %p", mModuleName, mHwDevice);
278}
279
Mikhail Naganov0bbc4aa2017-12-22 13:23:08 -0800280SoundTriggerHalImpl::~SoundTriggerHalImpl() {
Eric Laurent27ef4d82016-10-14 15:46:06 -0700281 if (mHwDevice != NULL) {
282 sound_trigger_hw_device_close(mHwDevice);
283 }
284}
285
Mikhail Naganovdfdc3bb2017-12-22 13:35:23 -0800286uint32_t SoundTriggerHalImpl::nextUniqueModelId() {
287 uint32_t modelId = 0;
288 {
289 AutoMutex lock(mLock);
290 do {
291 modelId =
292 atomic_fetch_add_explicit(&mNextModelId, (uint_fast32_t)1, memory_order_acq_rel);
293 } while (mClients.valueFor(modelId) != 0 && modelId != 0);
294 }
295 LOG_ALWAYS_FATAL_IF(modelId == 0, "wrap around in sound model IDs, num loaded models %zu",
296 mClients.size());
297 return modelId;
Eric Laurent27ef4d82016-10-14 15:46:06 -0700298}
299
Mikhail Naganov0bbc4aa2017-12-22 13:23:08 -0800300void SoundTriggerHalImpl::convertUuidFromHal(Uuid* uuid, const sound_trigger_uuid_t* halUuid) {
Eric Laurent27ef4d82016-10-14 15:46:06 -0700301 uuid->timeLow = halUuid->timeLow;
302 uuid->timeMid = halUuid->timeMid;
303 uuid->versionAndTimeHigh = halUuid->timeHiAndVersion;
304 uuid->variantAndClockSeqHigh = halUuid->clockSeq;
305 memcpy(&uuid->node[0], &halUuid->node[0], 6);
306}
307
Mikhail Naganov0bbc4aa2017-12-22 13:23:08 -0800308void SoundTriggerHalImpl::convertUuidToHal(sound_trigger_uuid_t* halUuid, const Uuid* uuid) {
Eric Laurent27ef4d82016-10-14 15:46:06 -0700309 halUuid->timeLow = uuid->timeLow;
310 halUuid->timeMid = uuid->timeMid;
311 halUuid->timeHiAndVersion = uuid->versionAndTimeHigh;
312 halUuid->clockSeq = uuid->variantAndClockSeqHigh;
313 memcpy(&halUuid->node[0], &uuid->node[0], 6);
314}
315
316void SoundTriggerHalImpl::convertPropertiesFromHal(
Mikhail Naganov0bbc4aa2017-12-22 13:23:08 -0800317 ISoundTriggerHw::Properties* properties, const struct sound_trigger_properties* halProperties) {
Eric Laurent27ef4d82016-10-14 15:46:06 -0700318 properties->implementor = halProperties->implementor;
319 properties->description = halProperties->description;
320 properties->version = halProperties->version;
321 convertUuidFromHal(&properties->uuid, &halProperties->uuid);
322 properties->maxSoundModels = halProperties->max_sound_models;
323 properties->maxKeyPhrases = halProperties->max_key_phrases;
324 properties->maxUsers = halProperties->max_users;
325 properties->recognitionModes = halProperties->recognition_modes;
326 properties->captureTransition = halProperties->capture_transition;
327 properties->maxBufferMs = halProperties->max_buffer_ms;
328 properties->concurrentCapture = halProperties->concurrent_capture;
329 properties->triggerInEvent = halProperties->trigger_in_event;
330 properties->powerConsumptionMw = halProperties->power_consumption_mw;
Eric Laurent27ef4d82016-10-14 15:46:06 -0700331}
332
Mikhail Naganov0bbc4aa2017-12-22 13:23:08 -0800333void SoundTriggerHalImpl::convertTriggerPhraseToHal(struct sound_trigger_phrase* halTriggerPhrase,
334 const ISoundTriggerHw::Phrase* triggerPhrase) {
Eric Laurent27ef4d82016-10-14 15:46:06 -0700335 halTriggerPhrase->id = triggerPhrase->id;
336 halTriggerPhrase->recognition_mode = triggerPhrase->recognitionModes;
337 unsigned int i;
Eric Laurenta6920302017-09-07 12:35:29 -0700338
339 halTriggerPhrase->num_users =
340 std::min((int)triggerPhrase->users.size(), SOUND_TRIGGER_MAX_USERS);
341 for (i = 0; i < halTriggerPhrase->num_users; i++) {
Eric Laurent27ef4d82016-10-14 15:46:06 -0700342 halTriggerPhrase->users[i] = triggerPhrase->users[i];
343 }
Eric Laurent27ef4d82016-10-14 15:46:06 -0700344
Mikhail Naganov0bbc4aa2017-12-22 13:23:08 -0800345 strlcpy(halTriggerPhrase->locale, triggerPhrase->locale.c_str(), SOUND_TRIGGER_MAX_LOCALE_LEN);
346 strlcpy(halTriggerPhrase->text, triggerPhrase->text.c_str(), SOUND_TRIGGER_MAX_STRING_LEN);
Eric Laurent27ef4d82016-10-14 15:46:06 -0700347}
348
Mikhail Naganov0bbc4aa2017-12-22 13:23:08 -0800349struct sound_trigger_sound_model* SoundTriggerHalImpl::convertSoundModelToHal(
350 const ISoundTriggerHw::SoundModel* soundModel) {
351 struct sound_trigger_sound_model* halModel = NULL;
Eric Laurent27ef4d82016-10-14 15:46:06 -0700352 if (soundModel->type == SoundModelType::KEYPHRASE) {
353 size_t allocSize =
Mikhail Naganov0bbc4aa2017-12-22 13:23:08 -0800354 sizeof(struct sound_trigger_phrase_sound_model) + soundModel->data.size();
355 struct sound_trigger_phrase_sound_model* halKeyPhraseModel =
356 static_cast<struct sound_trigger_phrase_sound_model*>(malloc(allocSize));
Eric Laurent27ef4d82016-10-14 15:46:06 -0700357 LOG_ALWAYS_FATAL_IF(halKeyPhraseModel == NULL,
Mikhail Naganov0bbc4aa2017-12-22 13:23:08 -0800358 "malloc failed for size %zu in convertSoundModelToHal PHRASE",
359 allocSize);
Eric Laurent27ef4d82016-10-14 15:46:06 -0700360
Mikhail Naganov0bbc4aa2017-12-22 13:23:08 -0800361 const ISoundTriggerHw::PhraseSoundModel* keyPhraseModel =
362 reinterpret_cast<const ISoundTriggerHw::PhraseSoundModel*>(soundModel);
Eric Laurent27ef4d82016-10-14 15:46:06 -0700363
364 size_t i;
365 for (i = 0; i < keyPhraseModel->phrases.size() && i < SOUND_TRIGGER_MAX_PHRASES; i++) {
Mikhail Naganov0bbc4aa2017-12-22 13:23:08 -0800366 convertTriggerPhraseToHal(&halKeyPhraseModel->phrases[i], &keyPhraseModel->phrases[i]);
Eric Laurent27ef4d82016-10-14 15:46:06 -0700367 }
368 halKeyPhraseModel->num_phrases = (unsigned int)i;
Mikhail Naganov0bbc4aa2017-12-22 13:23:08 -0800369 halModel = reinterpret_cast<struct sound_trigger_sound_model*>(halKeyPhraseModel);
Eric Laurent27ef4d82016-10-14 15:46:06 -0700370 halModel->data_offset = sizeof(struct sound_trigger_phrase_sound_model);
371 } else {
Mikhail Naganov0bbc4aa2017-12-22 13:23:08 -0800372 size_t allocSize = sizeof(struct sound_trigger_sound_model) + soundModel->data.size();
373 halModel = static_cast<struct sound_trigger_sound_model*>(malloc(allocSize));
Eric Laurent27ef4d82016-10-14 15:46:06 -0700374 LOG_ALWAYS_FATAL_IF(halModel == NULL,
375 "malloc failed for size %zu in convertSoundModelToHal GENERIC",
376 allocSize);
377
378 halModel->data_offset = sizeof(struct sound_trigger_sound_model);
379 }
380 halModel->type = (sound_trigger_sound_model_type_t)soundModel->type;
381 convertUuidToHal(&halModel->uuid, &soundModel->uuid);
382 convertUuidToHal(&halModel->vendor_uuid, &soundModel->vendorUuid);
383 halModel->data_size = soundModel->data.size();
Mikhail Naganov0bbc4aa2017-12-22 13:23:08 -0800384 uint8_t* dst = reinterpret_cast<uint8_t*>(halModel) + halModel->data_offset;
385 const uint8_t* src = reinterpret_cast<const uint8_t*>(&soundModel->data[0]);
Eric Laurent27ef4d82016-10-14 15:46:06 -0700386 memcpy(dst, src, soundModel->data.size());
387
388 return halModel;
389}
390
391void SoundTriggerHalImpl::convertPhraseRecognitionExtraToHal(
Mikhail Naganov0bbc4aa2017-12-22 13:23:08 -0800392 struct sound_trigger_phrase_recognition_extra* halExtra, const PhraseRecognitionExtra* extra) {
Eric Laurent27ef4d82016-10-14 15:46:06 -0700393 halExtra->id = extra->id;
394 halExtra->recognition_modes = extra->recognitionModes;
395 halExtra->confidence_level = extra->confidenceLevel;
396
397 unsigned int i;
398 for (i = 0; i < extra->levels.size() && i < SOUND_TRIGGER_MAX_USERS; i++) {
399 halExtra->levels[i].user_id = extra->levels[i].userId;
400 halExtra->levels[i].level = extra->levels[i].levelPercent;
401 }
402 halExtra->num_levels = i;
403}
404
Mikhail Naganov0bbc4aa2017-12-22 13:23:08 -0800405struct sound_trigger_recognition_config* SoundTriggerHalImpl::convertRecognitionConfigToHal(
406 const ISoundTriggerHw::RecognitionConfig* config) {
Eric Laurent27ef4d82016-10-14 15:46:06 -0700407 size_t allocSize = sizeof(struct sound_trigger_recognition_config) + config->data.size();
Mikhail Naganov0bbc4aa2017-12-22 13:23:08 -0800408 struct sound_trigger_recognition_config* halConfig =
409 static_cast<struct sound_trigger_recognition_config*>(malloc(allocSize));
Eric Laurent27ef4d82016-10-14 15:46:06 -0700410
411 LOG_ALWAYS_FATAL_IF(halConfig == NULL,
Mikhail Naganov0bbc4aa2017-12-22 13:23:08 -0800412 "malloc failed for size %zu in convertRecognitionConfigToHal", allocSize);
Eric Laurent27ef4d82016-10-14 15:46:06 -0700413
414 halConfig->capture_handle = (audio_io_handle_t)config->captureHandle;
415 halConfig->capture_device = (audio_devices_t)config->captureDevice;
416 halConfig->capture_requested = config->captureRequested;
417
418 unsigned int i;
419 for (i = 0; i < config->phrases.size() && i < SOUND_TRIGGER_MAX_PHRASES; i++) {
Mikhail Naganov0bbc4aa2017-12-22 13:23:08 -0800420 convertPhraseRecognitionExtraToHal(&halConfig->phrases[i], &config->phrases[i]);
Eric Laurent27ef4d82016-10-14 15:46:06 -0700421 }
422 halConfig->num_phrases = i;
423
424 halConfig->data_offset = sizeof(struct sound_trigger_recognition_config);
425 halConfig->data_size = config->data.size();
Mikhail Naganov0bbc4aa2017-12-22 13:23:08 -0800426 uint8_t* dst = reinterpret_cast<uint8_t*>(halConfig) + halConfig->data_offset;
427 const uint8_t* src = reinterpret_cast<const uint8_t*>(&config->data[0]);
Eric Laurent27ef4d82016-10-14 15:46:06 -0700428 memcpy(dst, src, config->data.size());
429 return halConfig;
430}
431
432// static
Mikhail Naganov0bbc4aa2017-12-22 13:23:08 -0800433void SoundTriggerHalImpl::convertSoundModelEventFromHal(
434 ISoundTriggerHwCallback::ModelEvent* event, const struct sound_trigger_model_event* halEvent) {
Eric Laurent27ef4d82016-10-14 15:46:06 -0700435 event->status = (ISoundTriggerHwCallback::SoundModelStatus)halEvent->status;
436 // event->model to be remapped by called
437 event->data.setToExternal(
Mikhail Naganov0bbc4aa2017-12-22 13:23:08 -0800438 const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(halEvent)) + halEvent->data_offset,
439 halEvent->data_size);
Eric Laurent27ef4d82016-10-14 15:46:06 -0700440}
441
442// static
Mikhail Naganovdfdc3bb2017-12-22 13:35:23 -0800443void SoundTriggerHalImpl::convertPhaseRecognitionEventFromHal(
444 ISoundTriggerHwCallback::PhraseRecognitionEvent* event,
445 const struct sound_trigger_phrase_recognition_event* halEvent) {
446 event->phraseExtras.resize(halEvent->num_phrases);
447 for (unsigned int i = 0; i < halEvent->num_phrases; i++) {
448 convertPhraseRecognitionExtraFromHal(&event->phraseExtras[i], &halEvent->phrase_extras[i]);
Eric Laurent27ef4d82016-10-14 15:46:06 -0700449 }
Mikhail Naganovdfdc3bb2017-12-22 13:35:23 -0800450 convertRecognitionEventFromHal(&event->common, &halEvent->common);
451}
Eric Laurent27ef4d82016-10-14 15:46:06 -0700452
Mikhail Naganovdfdc3bb2017-12-22 13:35:23 -0800453// static
454void SoundTriggerHalImpl::convertRecognitionEventFromHal(
455 ISoundTriggerHwCallback::RecognitionEvent* event,
456 const struct sound_trigger_recognition_event* halEvent) {
Eric Laurent27ef4d82016-10-14 15:46:06 -0700457 event->status = static_cast<ISoundTriggerHwCallback::RecognitionStatus>(halEvent->status);
458 event->type = static_cast<SoundModelType>(halEvent->type);
459 // event->model to be remapped by called
460 event->captureAvailable = halEvent->capture_available;
461 event->captureSession = halEvent->capture_session;
462 event->captureDelayMs = halEvent->capture_delay_ms;
463 event->capturePreambleMs = halEvent->capture_preamble_ms;
464 event->triggerInData = halEvent->trigger_in_data;
465 event->audioConfig.sampleRateHz = halEvent->audio_config.sample_rate;
466 event->audioConfig.channelMask =
Mikhail Naganov0bbc4aa2017-12-22 13:23:08 -0800467 (audio::common::V2_0::AudioChannelMask)halEvent->audio_config.channel_mask;
Eric Laurent27ef4d82016-10-14 15:46:06 -0700468 event->audioConfig.format = (audio::common::V2_0::AudioFormat)halEvent->audio_config.format;
469 event->data.setToExternal(
Mikhail Naganov0bbc4aa2017-12-22 13:23:08 -0800470 const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(halEvent)) + halEvent->data_offset,
471 halEvent->data_size);
Eric Laurent27ef4d82016-10-14 15:46:06 -0700472}
473
474// static
475void SoundTriggerHalImpl::convertPhraseRecognitionExtraFromHal(
Mikhail Naganov0bbc4aa2017-12-22 13:23:08 -0800476 PhraseRecognitionExtra* extra, const struct sound_trigger_phrase_recognition_extra* halExtra) {
Eric Laurent27ef4d82016-10-14 15:46:06 -0700477 extra->id = halExtra->id;
478 extra->recognitionModes = halExtra->recognition_modes;
479 extra->confidenceLevel = halExtra->confidence_level;
480
Eric Laurent27ef4d82016-10-14 15:46:06 -0700481 extra->levels.resize(halExtra->num_levels);
Mikhail Naganovdfdc3bb2017-12-22 13:35:23 -0800482 for (unsigned int i = 0; i < halExtra->num_levels; i++) {
483 extra->levels[i].userId = halExtra->levels[i].user_id;
484 extra->levels[i].levelPercent = halExtra->levels[i].level;
485 }
Eric Laurent27ef4d82016-10-14 15:46:06 -0700486}
487
Mikhail Naganovdfdc3bb2017-12-22 13:35:23 -0800488void SoundTriggerHalImpl::SoundModelClient_2_0::recognitionCallback(
489 struct sound_trigger_recognition_event* halEvent) {
490 if (halEvent->type == SOUND_MODEL_TYPE_KEYPHRASE) {
491 ISoundTriggerHwCallback::PhraseRecognitionEvent event;
492 convertPhaseRecognitionEventFromHal(
493 &event, reinterpret_cast<sound_trigger_phrase_recognition_event*>(halEvent));
494 event.common.model = mId;
495 mCallback->phraseRecognitionCallback(event, mCookie);
496 } else {
497 ISoundTriggerHwCallback::RecognitionEvent event;
498 convertRecognitionEventFromHal(&event, halEvent);
499 event.model = mId;
500 mCallback->recognitionCallback(event, mCookie);
501 }
Eric Laurent27ef4d82016-10-14 15:46:06 -0700502}
Mikhail Naganovdfdc3bb2017-12-22 13:35:23 -0800503
504void SoundTriggerHalImpl::SoundModelClient_2_0::soundModelCallback(
505 struct sound_trigger_model_event* halEvent) {
506 ISoundTriggerHwCallback::ModelEvent event;
507 convertSoundModelEventFromHal(&event, halEvent);
508 event.model = mId;
509 mCallback->soundModelCallback(event, mCookie);
510}
511
Mikhail Naganov0bbc4aa2017-12-22 13:23:08 -0800512} // namespace implementation
Eric Laurent27ef4d82016-10-14 15:46:06 -0700513} // namespace V2_0
514} // namespace soundtrigger
515} // namespace hardware
516} // namespace android